天天看點

【Maven由淺入深】6.maven的依賴特性

之前我們做了3個子產品,user-core、user-log和user-service,之間展現出了互相依賴的特性。

接下來我們要說依賴中幾個比較重要的概念。

有沒有發現我們的pom檔案的<dependency></dependency>标簽對可以設定一個<scope></scope>标簽對,然後其中的值有compile、import、provided、runtime、system、test。

system和import我們先不說。說一下compile、provided、runtime和test。

compile:

我們的依賴範圍是基于compile的依賴範圍,也是我們的預設依賴範圍。當<scope></scope>标簽對中是compile時,它會在編譯或打包的時候把依賴加進去,這就是compile的範圍。

provided:

當我們編譯、測試的時候會把依賴加進去,但是當我們打包的時候就不會把依賴加進去。(例如我們做web需要servlet-api.jar,但是我們的tomcat的lib中是有這個包的,我們最後給項目打包的時候如果把servlet-api.jar依賴也加進去的話,就會發生沖突。)

runtime:

在運作的時候依賴,在編譯的時候不依賴。

test:

在測試範圍内依賴有效,在編譯和打包的時候不會使用這個依賴。(例如我們使用的測試jar包junit,在項目正式啟動後這個包就不需要了,是以我們僅在測試中使用這個依賴,編譯和打包的時候就不需要了,即節省了編譯壓力提高了效率)

注意,如果我們将junit的scope設定成test,我們編譯的時候隻為test源檔案夾下的類提供junit依賴,src下其它檔案夾下的類不提供依賴,是以我們要注意,scope為test的依賴隻能提供給test檔案夾下的類,編寫的時候注意使用範圍。

我們注意到,我們的user-service子產品內建了user-core和user-log兩個子產品,而且引用了後兩者的依賴包,我們要注意,這裡內建的依賴包是後兩者編譯compile範圍内的依賴包,而不是所有的依賴包(scope不是預設的或不是compile)。

接來下我們來談一下依賴裡讓人比較頭疼的一些事。

假設我們有一個a項目,依賴了一個l-1.0.jar,然後我們有一個b項目,依賴了一個l-2.0.jar,然後我們又有一個c項目,及依賴于a,又依賴于b:

a--l1.0

b--l2.0

c--a,b

那麼c項目是引用的l-1.0.jar呢,還是引用l-2.0.jar呢?我們來試驗一下:

我們的user-core依賴的log4j版本是1.2.17:

【Maven由淺入深】6.maven的依賴特性

我們的user-log依賴的log4j版本是1.2.9:

【Maven由淺入深】6.maven的依賴特性

那內建這兩個項目的user-service,使用的log4j是什麼版本的?

我們看一下:

【Maven由淺入深】6.maven的依賴特性

為什麼?我們看一下user-service的pom檔案:

發現我們是先引入的user-log,後引入的user-core:

【Maven由淺入深】6.maven的依賴特性

是以先引入了log4j-1.2.9,然後引入user-core的時候發現已經存在log4j的jar,是以就沒有重複引入。

是以abc之間,a、b和l的依賴是直接依賴,c和l的依賴是間接依賴。當我們有了間接依賴之後,先聲明了哪個使用該依賴的子產品,就間接使用哪個依賴。

接下來看下一點:

如果級别相同,哪一個先寫依賴哪一個,那麼我們看一下這個情況:

我們現在将user-log和user-core的依賴先後調換一下:

【Maven由淺入深】6.maven的依賴特性

首先看我們的log4j,使用的就是1.2.17了:

【Maven由淺入深】6.maven的依賴特性

這一點是沒有問題的,但是看我們的common-logging版本:

【Maven由淺入深】6.maven的依賴特性

是1.1.1對吧?回來看一下我們user-core和user-log的common-logging版本:

【Maven由淺入深】6.maven的依賴特性
【Maven由淺入深】6.maven的依賴特性

發現user-core的版本是1.0.4,根據我們“哪一個先寫依賴哪一個”的規則,應該是引用common-logging-1.0.4才對,但是為什麼引用的是user-log的1.1.1呢?

我們打開user-core的pom的依賴級層圖:

【Maven由淺入深】6.maven的依賴特性

發現user-core的common-logging是間接依賴,也就是說是dbunit使用的common-logging。

而我們看一下user-log的common-logging的依賴關系:

【Maven由淺入深】6.maven的依賴特性

發現是直接依賴關系。

是以,當依賴級别相同的時候,相同的jar,我們是哪個先被依賴就依賴那個子產品的jar,前提是,此jar我們隻依賴它“依賴層數”最短的jar。

這就是為什麼會使用common-logging的1.1.1版本。

能不能限制某些依賴的使用呢?假設我們就想用common-logging的1.0.4版本,我們可在user-service的pom檔案中這樣修改:

【Maven由淺入深】6.maven的依賴特性

這樣就排除使用user-log的commons-logging包了,我們再看user-service的依賴,發現已經變成1.0.4版本:

【Maven由淺入深】6.maven的依賴特性

是以,當依賴沖突的時候,我們可以通過exclusion排除包來解決依賴的沖突。

轉載請注明出處:http://blog.csdn.net/acmman/article/details/50628499