讀古今文學網 > Maven實戰 > 8.3.1 account-parent >

8.3.1 account-parent

面向對像設計中,程序員可以建立一種類的父子結構,然後在父類中聲明一些字段和方法供子類繼承,這樣就可以做到「一處聲明,多處使用」。類似地,我們需要創建POM的父子結構,然後在父POM中聲明一些配置供子POM繼承,以實現「一處聲明,多處使用」的目的。

我們繼續以賬戶註冊服務為基礎,在account-aggregator下創建一個名為account-parent的子目錄,然後在該子目錄下建立一個所有除account-aggregator之外模塊的父模塊。為此,在該子目錄創建一個pom.xml文件,內容見代碼清單8-10。

代碼清單8-10 account-parent的POM

該POM十分簡單,它使用了與其他模塊一致的groupId和version,使用的artifactId為account-parent表示這是一個父模塊。需要特別注意的是,它的packaging為pom,這一點與聚合模塊一樣,作為父模塊的POM,其打包類型也必須為pom。

由於父模塊只是為了幫助消除配置的重複,因此它本身不包含除POM之外的項目文件,也就不需要src/main/java/之類的文件夾了。

有了父模塊,就需要讓其他模塊來繼承它。首先將account-email的POM修改如下,見代碼清單8-11。

代碼清單8-11 修改account-email繼承account-parent

上述POM中使用parent元素聲明父模塊,parent下的子元素groupId、artifactId和version指定了父模塊的坐標,這三個元素是必須的。元素relativePath表示父模塊POM的相對路徑,該例中的../account-parent/pom.xml表示父POM的位置在與account-email/目錄平行的account-parent/目錄下。當項目構建時,Maven會首先根據relativePath檢查父POM,如果找不到,再從本地倉庫查找。relativePath的默認值是../pom.xml,也就是說,Maven默認父POM在上一層目錄下。

正確設置relativePath非常重要。考慮這樣一個情況,開發團隊的新成員從源碼庫簽出一個包含父子模塊關係的Maven項目。由於只關心其中的某一個子模塊,它就直接到該模塊的目錄下執行構建,這個時候,父模塊是沒有被安裝到本地倉庫的,因此如果子模塊沒有設置正確的relativePath,Maven將無法找到父POM,這將直接導致構建失敗。如果Maven能夠根據relativePath找到父POM,它就不需要再去檢查本地倉庫。

這個更新過的POM沒有為account-email聲明groupId和version,不過這並不代表account-email沒有groupId和version。實際上,這個子模塊隱式地從父模塊繼承了這兩個元素,這也就消除了一些不必要的配置。在該例中,父子模塊使用同樣的groupId和version,如果遇到子模塊需要使用和父模塊不一樣的groupId或者version的情況,那麼用戶完全可以在子模塊中顯式聲明。對於artifactId元素來說,子模塊應該顯式聲明,一方面,如果完全繼承groupId、artifactId和version,會造成坐標衝突;另一方面,即使使用不同的groupId或version,同樣的artifactId容易造成混淆。

為了節省篇幅,上述POM中省略了依賴配置和插件配置,稍後本章會介紹如何將共同的依賴配置提取到父模塊中。

與account-email的POM類似,以下是account-persist更新後的POM,見代碼清單8-12。

代碼清單8-12 修改account-persist繼承account-parent

最後,同樣還需要把account-parent加入到聚合模塊account-aggregator中,見代碼清單8-13。

代碼清單8-13 將account-parent加入到聚合模塊