情景一:
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以供我们学习或者解决我们的实际问题。