在上一篇文章中咱们已经介绍了依赖性,此次咱们再来介绍下传递依赖的问题,首先咱们仍是在上篇文章基础之上进行编写。java
一、上篇文章中已经创建了一个user-core的模块,如今首先再创建一个user-log的模块,在此模块中引入log4j、commons-logging等包:mysql
1 <dependencies> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>4.10</version> 6 <scope>test</scope> 7 </dependency> 8 <dependency> 9 <groupId>log4j</groupId> 10 <artifactId>log4j</artifactId> 11 <version>1.2.11</version> 12 </dependency> 13 <dependency> 14 <groupId>commons-logging</groupId> 15 <artifactId>commons-logging</artifactId> 16 <version>1.1.3</version> 17 </dependency> 18 </dependencies>
注意咱们这里使用的log4j的版本和在user-core中使用的log4j的版本号是不一样的哦。sql
为了方便咱们在user-log中定义了一个Log类以下:maven
1 package com.lq.wangzhen.user.log; 2 3 public class Log { 4 5 public void print(String str){ 6 System.out.println("hello:"+str); 7 } 8 }
user-log的结构图以下:spa
二、下面再创建一个项目user-dao模块,在这个模块中咱们要对user类进行操做,因此要导入user-core模块:hibernate
1 <dependencies> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>3.8.1</version> 6 <scope>test</scope> 7 </dependency> 8 <dependency> 9 <groupId>com.lq.wangzhen.user</groupId> 10 <artifactId>user-core</artifactId> 11 <version>0.0.1-SNAPSHOT</version> 12 </dependency> 13 </dependencies>
此时咱们并无在user-dao用引入hibernate的jar包,只是引用了user-core,可是咱们也在user-dao中发现了hibernate的jar包,这个就是传递性依赖。3d
对于传递性依赖这里再作一点解释,就是这里user-core依赖于hibernate,而user-dao依赖于user-core,因此user-dao也会依赖于hibernate,这种依赖咱们成为是基于compile的依赖,这个是经过scope进行配置的,咱们能够在junit依赖中都配置了scope属性,若是此属性没有配置的话,则默认的是compile范围的,而对于scope为test类型的话,则不会进行传递依赖,好比下载咱们把user-dao中依赖的junit去掉,以下:code
1 <dependencies> 2 <dependency> 3 <groupId>com.lq.wangzhen.user</groupId> 4 <artifactId>user-core</artifactId> 5 <version>0.0.1-SNAPSHOT</version> 6 </dependency> 7 </dependencies>
此时只依赖了user-core,而user-core中依赖了junit,以下:xml
1 <dependencies> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>4.10</version> 6 <scope>test</scope> 7 </dependency> 8 <dependency> 9 <groupId>org.hibernate</groupId> 10 <artifactId>hibernate-core</artifactId> 11 <version>4.2.5.Final</version> 12 </dependency> 13 <dependency> 14 <groupId>log4j</groupId> 15 <artifactId>log4j</artifactId> 16 <version>1.2.17</version> 17 </dependency> 18 <dependency> 19 <groupId>mysql</groupId> 20 <artifactId>mysql-connector-java</artifactId> 21 <version>5.1.26</version> 22 </dependency> 23 </dependencies>
可是咱们能够发如今其中配置了scope属性为test,因此不会发生传递依赖,即咱们的user-dao项目中不会有junit的jar包:blog
能够发现其中并无junit的jar包。
三、如今再让user-dao项目依赖user-log项目:
1 <dependencies> 2 <dependency> 3 <groupId>com.lq.wangzhen.user</groupId> 4 <artifactId>user-core</artifactId> 5 <version>0.0.1-SNAPSHOT</version> 6 </dependency> 7 <dependency> 8 <groupId>com.lq.wangzhen.user</groupId> 9 <artifactId>user-log</artifactId> 10 <version>0.0.1-SNAPSHOT</version> 11 </dependency> 12 </dependencies>
由于咱们在user-core和user-log中都使用了log4j,而且user-core中使用的是1.2.17版本的,而user-log中使用的是1.2.11版本的,那此时在user-dao中最终会引用那个版本的呢?
咱们能够看到引用的是user-core中的1.2.17版本的,这是为何呢?此时咱们把在user-dao中依赖user-core和user-log的顺序给调换一下,以下:
1 <dependencies> 2 <dependency> 3 <groupId>com.lq.wangzhen.user</groupId> 4 <artifactId>user-log</artifactId> 5 <version>0.0.1-SNAPSHOT</version> 6 </dependency> 7 <dependency> 8 <groupId>com.lq.wangzhen.user</groupId> 9 <artifactId>user-core</artifactId> 10 <version>0.0.1-SNAPSHOT</version> 11 </dependency> 12 </dependencies>
此时再观察结果:
此时咱们能够看出这里引用的是user-log中的1.2.11版本的log4j,此时咱们彷佛明白了,在user-dao中先引用的是哪一个项目就会使用此项目中的jar包,若是jar包有冲突的话。
四、到此,咱们在以上项目的基础上再创建一个maven项目,命名为user-services,在此项目中依赖于user-dao,user-log,以下:
1 <dependencies> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>3.8.1</version> 6 <scope>test</scope> 7 </dependency> 8 <dependency> 9 <groupId>com.lq.wangzhen.user</groupId> 10 <artifactId>user-dao</artifactId> 11 <version>0.0.1-SNAPSHOT</version> 12 </dependency> 13 <dependency> 14 <groupId>com.lq.wangzhen.user</groupId> 15 <artifactId>user-log</artifactId> 16 <version>0.0.1-SNAPSHOT</version> 17 </dependency> 18 </dependencies>
此时先引用了user-dao,而在user-dao中先引用了user-core,因此user-dao中的log4j的版本是1.2.17版本的,而user-log中的log4j是1.2.11版本的,此时user-services中的log4j是哪一个版本呢?咱们看图:
这里发现引用的是1.2.11版本,这是为何呢?咱们明明是先引用的user-dao,而user-dao中的是1.2.17版本的,为何是这个版本呢?这是由于:
user-core依赖于log4j 1.2.17
user-log依赖于log4j 1.2.11
user-dao依赖于user-core和user-log,最终依赖于log4j 1.2.17
user-services依赖于user-dao和user-log,此时从user-services找到log4j须要通过user-dao、user-core,须要两步,而从user-log找到log4j只须要一步,因此最终会选择user-log中的log4j,这是maven中的最小路径问题。那么这个选择咱们能不能控制呢?固然!咱们能够修改user-services中的pom.xml,在依赖于user-log时排除对log的依赖,以下:
1 <dependencies> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>3.8.1</version> 6 <scope>test</scope> 7 </dependency> 8 <dependency> 9 <groupId>com.lq.wangzhen.user</groupId> 10 <artifactId>user-dao</artifactId> 11 <version>0.0.1-SNAPSHOT</version> 12 </dependency> 13 <dependency> 14 <groupId>com.lq.wangzhen.user</groupId> 15 <artifactId>user-log</artifactId> 16 <version>0.0.1-SNAPSHOT</version> 17 <exclusions> 18 <exclusion> 19 <groupId>log4j</groupId> 20 <artifactId>log4j</artifactId> 21 </exclusion> 22 </exclusions> 23 </dependency> 24 </dependencies>
这样user-services就会依赖于user-dao中的log4j了。