讀古今文學網 > Maven實戰 > 8.3.3 依賴管理 >

8.3.3 依賴管理

上一節的可繼承元素列表包含了dependencies元素,說明依賴是會被繼承的,這時我們就會很容易想到將這一特性應用到account-parent中。子模塊account-email和account-persist同時依賴了org.springframework:spring-core:2.5.6、org.springframework:spring-beans:2.5.6、org.springframework:spring-context:2.5.6和junit:junit:4.7,因此可以將這些依賴配置放到父模塊account-parent中,兩個子模塊就能移除這些依賴,簡化配置。

上述做法是可行的,但卻存在問題。到目前為止,我們能夠確定這兩個子模塊都包含那四個依賴,不過我們無法確定將來添加的子模塊就一定需要這四個依賴。假設將來項目中需要加入一個account-util模塊,該模塊只是提供一些簡單的幫助工具,與springframework完全無關,難道也讓它依賴spring-core、spring-beans和spring-context嗎?那顯然是不合理的。

Maven提供的dependencyManagement元素既能讓子模塊繼承到父模塊的依賴配置,又能保證子模塊依賴使用的靈活性。在dependencyManagement元素下的依賴聲明不會引入實際的依賴,不過它能夠約束dependencies下的依賴使用。例如,可以在account-parent中加入這樣的dependencyManagement配置,見代碼清單8-14。

代碼清單8-14 在account-parent中配置dependencyManagement元素

首先該父POM使用了5.9.2節介紹的方法,將springframework和junit依賴的版本以Maven變量的形式提取了出來,不僅消除了一些重複,也使得各依賴的版本處於更加明顯的位置。

這裡使用dependencyManagement聲明的依賴既不會給account-parent引入依賴,也不會給它的子模塊引入依賴,不過這段配置是會被繼承的。現在修改account-email的POM如下,見代碼清單8-15。

代碼清單8-15 繼承了dependencyManagement的account-email POM

上述POM中的依賴配置較原來簡單了一些,所有的springframework依賴只配置了groupId和artifactId,省去了version,而junit依賴不僅省去了version,還省去了依賴範圍scope。這些信息可以省略是因為account-email繼承了account-parent中的dependencyManagement配置,完整的依賴聲明已經包含在父POM中,子模塊只需要配置簡單的groupId和artifactId就能獲得對應的依賴信息,從而引入正確的依賴。

使用這種依賴管理機制似乎不能減少太多的POM配置,不過筆者還是強烈推薦採用這種方法。其主要原因在於在父POM中使用dependencyManagement聲明依賴能夠統一項目範圍中依賴的版本,當依賴版本在父POM中聲明之後,子模塊在使用依賴的時候就無須聲明版本,也就不會發生多個子模塊使用依賴版本不一致的情況。這可以幫助降低依賴衝突的幾率。

如果子模塊不聲明依賴的使用,即使該依賴已經在父POM的dependencyManagement中聲明了,也不會產生任何實際的效果,如account-persist的POM,見代碼清單8-16。

代碼清單8-16 繼承了dependencyManagement的account-persist POM

這裡沒有聲明spring-context-support,那麼該依賴就不會被引入。這正是dependencyManagement的靈活性所在。

5.5節在介紹依賴範圍的時候提到了名為import的依賴範圍,推遲到現在介紹是因為該範圍的依賴只在dependencyManagement元素下才有效果,使用該範圍的依賴通常指向一個POM,作用是將目標POM中的dependencyManagement配置導入併合並到當前POM的dependencyManagement元素中。例如想要在另外一個模塊中使用與代碼清單8-14完全一樣的dependencyManagement配置,除了複製配置或者繼承這兩種方式之外,還可以使用import範圍依賴將這一配置導入,見代碼清單8-17。

代碼清單8-17 使用import範圍依賴導入依賴管理配置

注意,上述代碼中依賴的type值為pom,import範圍依賴由於其特殊性,一般都是指向打包類型為pom的模塊。如果有多個項目,它們使用的依賴版本都是一致的,則就可以定義一個使用dependencyManagement專門管理依賴的POM,然後在各個項目中導入這些依賴管理配置。