maven 是一个常用的 java 跨平台项目管理工具,主要工作是项目构建、依赖管理和项目信息管理。 除了编写源代码,我们每天有相当一部分时间花在了编译、运行单元测试、生成文档、打包和部署等繁琐而不起眼的工作上,这就是项目的构建过程。 而 maven 可以自动地从清理、编译、测试到生成报告、打包、部署,极大的简化了我们日常的工作,同时它还是一个依赖管理工具和项目信息管理工具,提供了中央仓库,能帮助我们自动下载构件。 作为 java 程序员必备的工具,深入研究和了解 maven 的使用是非常重要的,尤其是在构建失败、包冲突解决时,只有了解了我们即将介绍的 maven 工具的用法和要点才不会一筹莫展。 本文我们就来重点介绍一下 maven 作为依赖管理和项目信息管理工具的使用。
maven 最强大的功能就是项目中依赖的管理。 根元素 project 下的 dependencies 可以包含一个或多个 dependency 元素,以声明一个或者多个项目依赖。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
如上所示,maven 依赖由以下几个元素构成:
元素 | 是否必须 | 备注 |
---|---|---|
groupId、artifactId、version | 是 | maven 依赖的基本坐标 |
tpye | 否 | 依赖的类型,默认为 jar |
scope | 否 | 依赖的范围 |
optional | 否 | 标记依赖是否可选 |
exclusions | 否 | 排除传递性依赖选项 |
maven 在不同的阶段,使用的包加载路径是不同的。
依赖范围就是用来控制依赖于这三种 classpath 的关系的,maven 有以下几种依赖范围可供选择:
依赖范围Scope | 对于compile classpath有效 | 对于test classpath有效 | 对于runtime classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | | Y | | JUnit |
provided | Y | Y | | servlet-api |
runtime | | Y | Y | JDBC 驱动实现 |
system | Y | Y | | 本地的 maven 仓库之类的类库文件 |
3.1. 依赖范围的传递性
如果 A 依赖 B,B 依赖 C,那么 C 对于 A 就是传递性依赖。 下表列出了依赖范围的传递性:
第一依赖 | |||||
---|---|---|---|---|---|
compile | test | provided | runtime | ||
第二依赖 | compile | compile | / | / | runtime |
test | test | / | / | test | |
provided | provided | / | provided | provided | |
runtime | runtime | / | / | runtime |
maven 依赖仲裁(Dependency Mediation)遵循以下两个原则: 1. 最短路径优先原则 2. 第一声明优先原则,在依赖路径长度相等的前提下,在POM中依赖声明最靠前的依赖优先
例如,项目A有这样的依赖关系: 1. A -> B -> C -> X(1.0),A -> D -> X(2.0),X(1.0) 路径长度为 3,X(2.0) 路径长度为 2,根据第一原则,X(2.0) 会被解析使用; 2. A -> B -> Y(1.0),A -> C -> Y(2.0),Y(1.0) 和 Y(2.0) 的依赖路径长度相同,如果 B 的依赖声明在C之前,那么 Y(1.0) 会被解析使用。
如果多个相关的依赖的版本都是相同的,可以使用 properties 元素定义 maven 属性,依赖的版本值用这一属性引用表示。
<properties>
<spring.version>2.5.6</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
Maven实战(Maven in Action) Maven权威指南。 Maven重要概念及最佳实践 — https://segmentfault.com/a/1190000000640821。 Maven依赖范围及传递 — https://blog.csdn.net/stypace/article/details/38440545