Maven依赖传递特性
Maven做为一个实用的工具简化了依赖导入的过程,也确保了依赖版本的正确,能够做到这一点的主要因素是具有依赖传递的特性。
如果有Maven项目A,项目A依赖了项目B,项目B依赖了项目C,那么我们可以说项目A就依赖了项目C。当执行项目A时,会自动把项目B和项目C都下载到项目A的jar包文件夹中,这就是依赖的传递特性。
Maven依赖传递原则
在A依赖B,B依赖C的前提下,C能否传递到A,取决于B依赖C时使用的依赖范围及配置:
- B依赖C时使用compile范围:可以传递。
- B依赖C时使用test或provided范围:不能传递。
- B依赖C时若配置了以下标签,不能传递:
总的来说,当依赖终止传递,是出现了以下情况:
- 非compile范围进行依赖传递
- 使用optional配置终止传递
- 依赖冲突(传递的依赖已存在)
Maven依赖冲突特性
当直接或间接应用出现相同的jar包,一个项目中就会出现重复的jar包,此时就视为依赖冲突。
当出现依赖冲突时,Maven会用自己的原则去自动解决冲突,对于重复的依赖去选择某一个进行终止依赖传递。同时对于依赖冲突的解决也可以使用手动的方式,不过一般不推荐。
Maven依赖冲突解决原则
自动选择原则
当依赖路径长度不同时,使用短路优先原则(第一原则),其选择逻辑如下。
A --->B--->C--->D--->X(Version 0.0.1)
B--->F--->X(Version 0.0.2)
则A依赖于X(Version 0.0.2)
当依赖路径长度相同时,使用先声明优先原则(第二原则),其选择逻辑如下。
A--->E--->X(Version 0.0.1)
A--->F--->X(Version 0.0.2)
则A依赖于X(Version 0.0.1)
在<dependencies></dependencies>中,先声明的,路径相同,会优先选择。
手动排除依赖冲突
当Maven自动排除依赖冲突的原则并不能达到自己项目特定需求时,可以使用手动排除依赖的方式,排除掉某些依赖中无需传递的部分,从而实现依赖冲突的解决。
通过<exclusions></exclusions>标签可以达到排除某个依赖不传递过来的目的。
在上图的样例中,该项目依赖maven_B项目,同时maven_B项目依赖了druid的某个版本,由于依赖的传递特性,可能本项目的某个其他依赖同样也依赖了druid的某个版本,两个druid版本发生了冲突,但本项目不需要使用的druid版本是maven_B项目所依赖的版本,所以可以使用上述方式来排除该druid版本,从而实现手动解决依赖冲突。