在上一篇文章中咱們已經介紹了依賴性,此次咱們再來介紹下傳遞依賴的問題,首先咱們仍是在上篇文章基礎之上進行編寫。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了。