maven使用入门(一)_依赖和坐标

在当前的编码工作中,几乎是百分之九十会使用 maven 了,但从来没系统地学习过,仅仅是照葫芦画瓢跟着使用,报错了也往往是去谷歌解决,所以为了更好地使用,系统学习 maven 是必要的。

maven 简单介绍

maven 主要服务于基于 java 平台的项目构建、依赖管理,和项目信息管理。

maven 的优点

  • maven 是跨平台的,因此无论是在 windows 还是 mac 上,都可以使用相同的命令。
  • 标准化构建过程,避免不必要的学习成本。

使用入门

pom 文件

maven 的 pom 文件定义了项目的一些基本信息,描述了项目如何构建,声明依赖。
一个简单的 pom 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>top.zhyee</groupId>
<artifactId>hello-world</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.9</version>
<scope>compile</scope>
</dependency>
</dependencies>

</project>

坐标

pom 文件中最重要的是 groupId、artifactId、version,这三个元素组成了项目的坐标,可以说是项目在 maven 世界中的名片。

  • groupId 定义了组的概念,实际工作中通常和公司关联,比如 io.daocloud.mircoservice
  • artifactId 定义了项目在当前组中的唯一 id,比如 hello-world
  • version 定义了项目当前版本,带有 SNAPSHOT 的表明项目处于开发阶段,还不稳定。

一般来说,项目中的包名都应该基于项目的 groupId 和 artifactId ,这样更加清晰。

打包方式

在上面的 pom 文件中,packaging 元素指定了项目的打包方式为 jar。其实这里不用显示指定,因为 maven 的默认打包方式为 jar。可以显示指定其他的打包方式,如 war。

依赖

dependencies 标签中声明了项目的依赖,maven 根据声明的坐标来找到依赖,scope 标签声明了依赖的范围,用来控制依赖与 classpaath 的关系。

maven 在编译项目主代码时需要一套 classpath,同时,在编译和测试时,又会使用另外的 classpath。因此,定义了依赖范围,就可以告诉 maven 是在什么情况下引入这个依赖。

依赖范围 编译 测试 运行
compile
test
provided
runtime
system
import

一些概念

传递性依赖

如果 A 依赖于 B , B 依赖于 C ,那么 maven 在解析 pom 时,会将 C 以传递性依赖的形式引入到 A。

依赖调解

假如有这样的依赖关系 A->B->C->D(1.0),A->F->D(2.0),那么最终引入的 D 会是哪个版本呢。

maven 依赖调解的第一原则是路径最近者优先,在这个例子中,2.0 版本更近,因此会被解析使用。

那么路径一样的情况下呢,如 A->C->D(1.0),A->F->D(2.0)

为了解决这个问题,maven 定义了依赖调解的第二原则,即第一声明者优先。在 pom 文件中定义的依赖顺序将决定哪一个版本的 jar 包会被解析使用。