1.依赖配置
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<classifier></classifier>
<scope>test</scope>
<type></type>
<optional></optional>
<exclusions>
<exclusion>
<artifactId></artifactId>
<groupId></groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
- groupId,artifactId:在上一章,坐标中已经说明,用于maven对于构件的定位
- version:版本
- classifier:用来定义构建输出的一些附属构建
- scope:依赖范围,有以下值
- compile,默认值,适用于所有阶段,会随着项目一起发布。
- provided,编译和测试的有用,在运行时无效,如servlet-api,在编译和测试的时候需要依赖,但是运行时,容器已经提供,所以不需要再次引入
- runtime,只在运行时使用,如JDBC驱动,适用运行和测试阶段。
- test,只在测试时使用,用于编译和运行测试代码。不会随项目发布。
- system,类似provided,需要再使用systemPath元素显示制定依赖文件路径,如下。(由于绑定本地文件,在其他计算机不一定存在,所以尽量不要使用)
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
- type:依赖类型,对应项目坐标定义的packaging,默认不用声明,为jar
- optional:标记依赖是否可选,有true和false。如果A依赖于B,但是B只是A在测试时使用,这个时候X依赖于A,那么A就不需要B,那么在A的pom中配置optional为true的话,则在x编译的时候会忽略B的依赖。
- exclusions:用来排除传递性依赖。比如,我们的项目A中引入了第三方构件B,但是B中又引入了C和D,但是D对于我们的项目有冲突那么我们可以配置如下,将D这个依赖忽略
<exclusion>
<artifactId>D</artifactId>
<groupId>D</groupId>
</exclusion>
2.依赖传递性
首先来看看依赖范围:
依赖范围 | 对编译classpath有效 | 对测试classpath有效 | 对于运行时编译classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | JUnit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | JDBC驱动实现 |
system | Y | Y | - | 本地的,Maven仓库以外的文件 |
如果我们在项目中配置一个依赖,但是这个依赖又有很多依赖,这样我们项目中就会存在许多不必要的jar,maven依赖传递性机制可以很好的解决这个问题。
如果A依赖B,我们叫第一直接依赖,B依赖C我们叫第二直接依赖,它们的依赖范围会随传递性产生变化。
如下,左边为第一直接依赖,上面为第二直接依赖,他们之间传递性关系如下:
compile | test | provided | runtime |
---|---|---|---|
compile | compile | - | - |
test | test | - | - |
provided | provided | - | provided |
runtime | runtime | - | - |
由上面可以知道,如果A依赖于B,范围为test,B依赖于C,范围为compile,那么C是A范围为test的传递性依赖
3.依赖调解原则
例子一
A->B->C->X(1.0),A->D->X(2.0)这里对于X有两个版本的依赖,那么哪个会被Maven解析?都被解析是不对的,会造成依赖重复。
maven依赖调解的第一原则:路径最近者优先,这里X(1.0)路径为3,X(2.0)为2,所以后者被解析使用。
例子二
但是如下问题,第一原则无法解决:
A->B->Y(1.0),A->C->Y(2.0),这里路径长度都是2,这里maven2.0.9开始又定义了第二原则:第一声明者优先
4.可选依赖
如果A->B
B中有如下依赖
<dependency>
<groupId>com.my.C</groupId>
<artifactId>cpt</artifactId>
<version>1.0.0</version>
<optional>true</optional>
</dependency>
通过上面配置,optional为true,那么A中就不会依赖这个cpt
5.排除依赖
snapshot–快照版和release–正式版
如果项目A依赖第三方依赖B,B又依赖SNAPSHOT版C那么C的不稳定会影响到A,这个时候就需要排除掉C。还有就是一个传递性依赖在中央仓库中对应的版本不存在,我们就需要排除依赖,然后再导入存在版本的依赖
<dependency>
<groupId>com.ys.b</groupId>
<artifactId>pro-b</artifactId>
<version>1.0.1</version>
<!--排除依赖-->
<exclusions>
<exclusion>
<groupId>com.ys.c</groupId>
<artifactId>pro-c</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入正确依赖 -->
<dependency>
<groupId>com.ys.c</groupId>
<artifactId>pro-c</artifactId>
<version>1.0.0</version>
</dependency>
可以用下图表示: