maven传递依赖规则

用maven很长时间了(2年),下面把一些需要注意的细节加以总结:
情景一:
learn-1 pom.xml
<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-core</artifactId>
     <version>4.1.4.RELEASE</version>
     <!--依赖commons-logging 1.2的版本-->
</dependency>
<dependency>
      <groupId>com.learn</groupId>
      <artifactId>learn2</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <!--依赖commons-logging 1.1.3的版本-->
      <optional>true</optional>     
</dependency>

learn-2 pom.xml
<dependency>
     <groupId>commons-logging</groupId>
     <artifactId>commons-logging</artifactId>
     <version>1.1.3</version>
</dependency>
<dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>3.8.1</version>
     <scope>test</scope>
</dependency>

mvn dependency:tree分别查看依赖情况:
[INFO] com.learn:learn2:jar:0.0.1-SNAPSHOT
[INFO] +- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] \- junit:junit:jar:3.8.1:test
[INFO] ------------------------------------------------------------------------

[INFO] com.learn:learn1:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:4.1.4.RELEASE:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.2:compile
[INFO] +- com.learn:learn2:jar:0.0.1-SNAPSHOT:compile
[INFO] \- junit:junit:jar:3.8.1:test
[INFO] ------------------------------------------------------------------------

结论:
learn1模块里的spring-core依赖common-logging的1.2版本,learn1依赖learn2,并且learn2也依赖common-logging,版本号是1.1.3。那么最后learn1将会依赖commons-logging的1.2版本,对于maven中的间接依赖,哪个依赖在pom文件中定义的位置在前面,就采用在前面定义的那个依赖。spring-core定义在learn2的前面,那么此时learn1就会依赖common-logging1.2的版本,如果spring-core和learn2的顺序调换一下,就会用commons-logging1.1.3的版本。
情景二:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <!-- 版本一 -->
    <version>2.0.6</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <!-- 版本二 -->
    <version>4.1.4.RELEASE</version>
</dependency>

分析结果:
[INFO] com.learn:learn1:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:4.1.4.RELEASE:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.2:compile

结论:
learn1将会依赖后声明的版本为4.1.4.RELEASE的spring-core依赖,一个Pom文件中声明了对一个项目的高低版本的依赖,使用最后声明者。
情景三:
learn-1依赖项目learn-2,learn-3,learn-2依赖commons-logging:1.1.3版本,learn-3依赖learn-4, learn-4依赖commons-logging:1.2版本。那么最终learn-1依赖的commons-logging版本将会是1.1.3 版本的。这是因为maven采用 最短路径优先原则

情景四(optional):
learn5 pom.xml
 <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <version>1.2</version>
       <optional>true</optional>
</dependency>

learn6 pom.xml
<dependency>
     <groupId>com.learn</groupId>
     <artifactId>learn5</artifactId>
     <version>0.0.1-SNAPSHOT</version>
</dependency>

分析结果:
[INFO] com.learn:learn6:jar:0.0.1-SNAPSHOT
[INFO] \- com.learn:learn5:jar:0.0.1-SNAPSHOT:compile

如果learn5把commons-logging的optional标签注释掉,分析的结果将不一样。
分析结果:
[INFO] 
com.learn:learn2:jar:0.0.1-SNAPSHOT
[INFO] \- com.learn:learn1:jar:0.0.1-SNAPSHOT:compile
[INFO]    \- commons-logging:commons-logging:jar:1.2:compile

结论:
optional标签如果设置为true,意味着子模块将不依赖此模块,如果想依赖这个jar,必须在自己的pom.xml文件中在声明一遍。官方文档说:这样做为了避免错误jar违反license出现问题或者classpath发生问题。
友情提示:
如果我们的项目依赖出现问题,请善用mvn dependency:tree来查看依赖情况。
在附上一个mvn插件链接 http://maven.apache.org/plugins/index.html以供我们学习或者解决我们的实际问题。

猜你喜欢

转载自zxy-920823.iteye.com/blog/2277646