1. 程式人生 > >Maven之聚合與繼承

Maven之聚合與繼承

1.聚合
 

<project>
<modelVersion>4.0.0</modelVersion>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<packaging>pom</packaging>
<name></name>
<modules>
<module></module>
<module></module>
</modules>
</project>


對於聚合模組來說,其打包方式packaging的值必須為pom,否則就無法構建。POM的name欄位是為了給專案提供一個更容易閱讀的名字。之後是元素modules,這是實現聚合的最核心的配置。使用者可以通過在一個打包方式為pom的Maven專案中宣告任意數量的module元素來實現模組的聚合。這裡每個module的值都是一個當前POM的相對目錄。
一般來說,為了方便快速定位內容,模組所處的目錄名稱應當與其artifactId一致,不過這不是Maven的要求,使用者也可以將account-email專案放到email-account/目錄下。這時,聚合的配置就需要相應地改成<module>email-account</module>。

2.繼承

<project>
<modelVersion>4.0.0</modelVersion>
<groupId></groupId>
<artifactId>parent</artifactId>
<version></version>
<packaging>pom</packaging>
<name></name>
</project>
<project>
<parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<relativePath>parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId></groupId>
<artifactId>child</artifactId>
<version></version>
<packaging>pom</packaging>
<name></name>
</project>


該POM十分簡單,它使用了與其他模組一致的groupId和version,使用的artifactId為account-parent表示這是一個父模組。需要特別注意的是,它的packaging為pom,這一點與聚合模組一樣,作為父模組的POM,其打包型別也必須為pom。
由於父模組只是為了幫助消除配置的重複,因此它本身不包含除POM之外的專案檔案,也就不需要src/main/java/之類的檔案夾了。有了父模組,就需要讓其他模組來繼承它。
上述POM中使用parent元素宣告父模組,parent下的子元素groupId、artifactId和version指定了父模組的座標,這三個元素是必須的。元素relativePath表示父模組POM的相對路徑,當專案構建時,Maven會首先根據relativePath檢查父POM,如果找不到,再從本地倉庫查詢。relativePath的預設值是../pom.xml,也就是說,Maven預設父POM在上一層目錄下。
正確設定relativePath非常重要。考慮這樣一個情況,開發團隊的新成員從原始碼庫簽出一個包含父子模組關係的Maven專案。由於只關心其中的某一個子模組,它就直接到該模組的目錄下執行構建,這個時候,父模組是沒有被安裝到本地倉庫的,因此如果子模組沒有設定正確的relativePath,Maven將無法找到父POM,這將直接導致構建失敗。如果Maven能夠根據relativePath找到父POM,它就不需要再去檢查本地倉庫。

3.可繼承的POM元素
groupId:專案組ID,專案座標的核心元素。
version:專案版本,專案座標的核心元素。
description:專案的描述資訊。
organization:專案的組織資訊。
inceptionYear:專案的創始年份。
url:專案的URL地址。
developers:專案的開發者資訊。
contributors:專案的貢獻者資訊。
distributionManagement:專案的部署配置。
issueManagement:專案的缺陷跟蹤系統資訊。
ciManagement:專案的持續整合系統資訊。
scm:專案的版本控制系統資訊。
mailingLists:專案的郵件列表資訊。
properties:自定義的Maven屬性。
dependencies:專案的依賴配置。
dependencyManagement:專案的依賴管理配置。
repositories:專案的倉庫配置。
build:包括專案的原始碼目錄配置、輸出目錄配置、外掛配置、外掛管理配置等。
reporting:包括專案的報告輸出目錄配置、報告外掛配置等。

4.依賴管理
Maven提供的dependencyManagement元素既能讓子模組繼承到父模組的依賴配置,又能保證子模組依賴使用的靈活性。在dependencyManagement元素下的依賴宣告不會引入實際的依賴,不過它能夠約束dependencies下的依賴使用。

<project>
<modelVersion>4.0.0</modelVersion>
<groupId></groupId>
<artifactId>parent</artifactId>
<version></version>
<packaging>pom</packaging>
<name></name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId></groupId><artifactId></artifactId><version></version>
</dependency>
...
</dependencies>
</dependencyManagement>
</project>
<project>
<parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<relativePath>parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId></groupId>
<artifactId>child</artifactId>
<version></version>
<packaging>pom</packaging>
<name></name>
<dependencies>
<dependency>
<groupId></groupId><artifactId></artifactId>
</dependency>
...
</dependencies>
</project>


上述POM中,所有的springframework依賴只配置了groupId和artifactId,省去了version,而junit依賴不僅省去了version,還省去了依賴範圍scope。這些資訊可以省略是因為子模組繼承了父模組中的dependencyManagement配置,完整的依賴宣告已經包含在父POM中,子模組只需要配置簡單的groupId和artifactId就能獲得對應的依賴資訊,從而引入正確的依賴。
使用這種依賴管理機制似乎不能減少太多的POM配置,不過筆者還是強烈推薦採用這種方法。其主要原因在於在父POM中使用dependencyManagement宣告依賴能夠統一專案範圍中依賴的版本,當依賴版本在父POM中宣告之後,子模組在使用依賴的時候就無須宣告版本,也就不會發生多個子模組使用依賴版本不一致的情況。這可以幫助降低依賴衝突的機率。
如果子模組不宣告依賴的使用,即使該依賴已經在父POM的dependencyManagement中聲明瞭,也不會產生任何實際的效果

5.scope:import依賴範圍
 

<dependencyManagement>
<dependencies>
<dependency>
<groupId></groupId>
<artifactId>parent</artifactId>
<version></version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>


使用該範圍的依賴通常指向一個POM,作用是將目標POM中的dependencyManagement配置匯入併合併到當前POM的dependencyManagement元素中。例如想要在另外一個模組中使用與程式碼清單8-14完全一樣的dependencyManagement配置,除了複製配置或者繼承這兩種方式之外,還可以使用import範圍依賴將這一配置匯入。
注意,上述程式碼中依賴的type值為pom,import範圍依賴由於其特殊性,一般都是指向打包型別為pom的模組。如果有多個專案,它們使用的依賴版本都是一致的,則就可以定義一個使用dependencyManagement專門管理依賴的POM,然後在各個專案中匯入這些依賴管理配置。

6.外掛管理
Maven提供了dependencyManagement元素幫助管理依賴,類似地,Maven也提供了pluginManagement元素幫助管理外掛。在該元素中配置的依賴不會造成實際的外掛呼叫行為,當POM中配置了真正的plugin元素,並且其groupId和artifactId與pluginManagement中配置的外掛匹配時,pluginManagement的配置才會影響實際的外掛行為。