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 包会被解析使用。