Maven 依赖
根元素 project 下的 dependencies 可以包含一个或多个dependency 元素,以声明一个或者多个项目依赖。每个依赖可以包含的元素有:
groupId,artifactId,version:依赖的基本坐标type:依赖的类型,大部分情况下不必声明,默认为jarscope:依赖的范围optional:标记依赖是否可选exclusions:用来排除传递性依赖
依赖范围
首先要弄清楚,Maven在不同的时候,使用了不同的classpath。Maven在编译项目主代码的时候使用compile classpath;在编译和执行测试的时候使用test classpath;在实际运行Maven项目的时候使用runtime classpath。
依赖范围就是用来控制依赖于这三种classpath(compile classpath, test classpath, runtime classpath)的关系。Maven有以下几种依赖范围:
compile:编译依赖范围,如果没有指定,默认使用该依赖范围test:测试依赖范围,使用此依赖范围的Maven依赖,只对test classpath有效provided:已提供依赖范围,使用此依赖范围的Maven依赖,对于compile和test classpath有效,但在运行时无效runtime:运行时依赖范围,使用此依赖范围的Maven依赖,对于test和runtime classpath有效,但在编译主代码时无效system:系统依赖范围,其与三种classpath的关系,和provided依赖范围一致
依赖范围与三种classpath的关系如下所示:
| 依赖范围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仓库职位的类库文件 |
传递性依赖
假设A依赖于B,B依赖于C,则A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。第一直接依赖和第二直接依赖决定了传递性依赖的范围,如下表所示,最左边一列表示第一直接依赖范围,最上面一行表示第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围。
| / | compile | test | provided | runtime |
|---|---|---|---|---|
| compile | compile | / | / | runtime |
| test | test | / | / | test |
| provided | provided | / | provided | provided |
| runtime | runtime | / | / | runtime |
依赖仲裁
Maven依赖仲裁(Dependency Mediation):
- 第一原则:最短路径优先原则
- 第二原则:第一声明优先原则,在依赖路径长度相等的前提下,在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)会被解析使用。
依赖相关的命令
mvn dependency:list列出最终确定的依赖mvn dependency:tree打出依赖树mvn dependency:analyze依赖分析,给出项目中已使用但未声明的依赖,以及未使用但已声明的依赖
POM优化
依赖管理
- 多模块项目中,定义一个主pom,在主pom中使用
dependencyManagement定义依赖、版本和依赖排除 - 子模块从主pom中继承依赖,一般情况下,不要在子模块中做依赖排除,也不要指定依赖版本
最佳实践
归类依赖
如果多个相关的依赖的版本都是相同的,可以使用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项目中的依赖管理,包括依赖范围、传递性依赖和依赖仲裁等内容,并提供了依赖相关的Maven命令及最佳实践。
362

被折叠的 条评论
为什么被折叠?



