<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<classifier>classifier>
<scope>testscope>
<type>type>
<optional>optional>
<exclusions>
<exclusion>
<artifactId>artifactId>
<groupId>groupId>
exclusion>
exclusions>
dependency>
dependencies>
<scope>systemscope>
<systemPath>${java.home}/lib/rt.jarsystemPath>
<exclusion>
<artifactId>DartifactId>
<groupId>DgroupId>
exclusion>
首先来看看依赖范围:
依赖范围 | 对编译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的传递性依赖
例子一
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开始又定义了第二原则:第一声明者优先
如果A->B
B中有如下依赖
<dependency>
<groupId>com.my.CgroupId>
<artifactId>cptartifactId>
<version>1.0.0version>
<optional>trueoptional>
dependency>
通过上面配置,optional为true,那么A中就不会依赖这个cpt
snapshot–快照版和release–正式版
如果项目A依赖第三方依赖B,B又依赖SNAPSHOT版C那么C的不稳定会影响到A,这个时候就需要排除掉C。还有就是一个传递性依赖在中央仓库中对应的版本不存在,我们就需要排除依赖,然后再导入存在版本的依赖
<dependency>
<groupId>com.ys.bgroupId>
<artifactId>pro-bartifactId>
<version>1.0.1version>
<exclusions>
<exclusion>
<groupId>com.ys.cgroupId>
<artifactId>pro-cartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.ys.cgroupId>
<artifactId>pro-cartifactId>
<version>1.0.0version>
dependency>
如果我们在pom中引入了多个依赖,比如spring相关的有core,beans,context等,这样如果我们需要修改版本,需要一个一个修改,十分麻烦
这个时候就可以使用properties来定义
<properties>
<spring.version>4.1.3.RELEASEspring.version>
properties>
在指定版本的时候用如下形式
<version>${spring.version}version>
mvn dependency:list以列表形式解析依赖
mvn dependency:tree以树的形式展示
配置公司项目,有两个依赖,mybatis-3.4.1和公司的包core(含mybatis3.2.1)
原先配置顺序为
<mybatis>
<core>
这个时候,项目是正常的,但是我中途调整了下他们的顺序
<core>
<mybatis>
就报异常
java.lang.NoClassDefFoundError: org/apache/ibatis/reflection/ReflectorFactory
ReflectorFactory在3.2中是不存在的,在3.4中是有的,而且看项目中导入的是3.2的版本
总结:依赖应该是以先定义的优先