你分得清楚Maven的聚合和繼承嗎?


用了 Maven 好幾年了,許多人還是只懂得簡單的依賴坐標。對於 Maven 的聚合和繼承還是一知半解,甚至很多人以為是同一個東西。但其實聚合是用於快速構建項目,是表示項目與子項目之間的關系。而繼承則是為消除重復的配置。下面通過一個例子深入聊聊這兩者的關系。

聚合

Maven 的聚合其實就是項目與子項目的表示,其存在的意義在於快速構建項目。例如我們有一個淘寶商城項目,這個項目有賬號子項目和郵件子項目。在這個時候我們需要在 Maven 中表達這種項目歸屬關系,那么我們就可以用 Maven 的聚合來進行配置。

我們首先創建一個 taobao-aggregator 項目,表示是一個聚合項目。之后再創建兩個子項目,分別為:com.chenshuyi.mail 和 com.chenshuyi.account。

//taobao-aggregator pom.xml
<groupId>com.chenshuyi</groupId>
<artifactId>taobao-aggregator</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>taobao-aggregator</name>
<modules>
    <module>mail</module>
    <module>account</module>
</modules>

可以看到 taobao-aggregator 的 pom.xml 文件中多了一個 modules 元素,其中包含了兩個子模塊。在 Maven 中我們通過 modules 元素來表示模塊之間的關聯關系。

在 Maven 的聚合關系中,聚合項目知道哪些項目是它的子項目,但是那些被聚合的項目並不知道其被哪個模塊聚合了。

一般情況下子項目都是在父項目的子目錄下,但你也可以把子項目放在與父項目同級的地方,只要你修改一下module元素的值即可。

//taobao/account/mail同級
<modules>
    <module>../account</module>
    <module>../mail</module>
</modules>

繼承

Maven 的繼承是為了消除重復配置而存在的。例如我們的 account 子模塊和 mail 子模塊都需要 junit-test 依賴,但是都得在自己的模塊里都寫一次,這樣豈不是會造成代碼的重復。這個時候就可以將共同的依賴寫在父類模塊中,讓子類繼承這些依賴。

例如 taobao-parent 是 mail 模塊和 account 模塊的父模塊,他們都需要 junit 測試依賴包。那么此時在 taobao-parent 項目的 dependencies 元素中聲明該依賴。

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
</dependencies>

mail 模塊和 account 模塊中增加一個 parent 元素聲明,表明其父級是 taobao-parent 項目。

<parent>
    <artifactId>taobao-parent</artifactId>
    <groupId>com.chenshuyi</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

經過這么一個配置之后,Maven 就只知道他們的依賴關系。此時 taobao 項目 dependencies 元素里聲明的依賴就會全部繼承到子項目中。這樣子項目中就不需要再去聲明多一次了,節省了不必要的配置。

像 dependencies 這樣可以被子類繼承的元素還有下面幾個元素:

  • groupId
  • version
  • description
  • organization
  • inceptionYear
  • url
  • developers
  • contributors
  • distributionManagement
  • issueManagement
  • ciManagement
  • scm
  • mailingLists
  • properties
  • dependencies
  • dependencyManagement
  • repositories
  • build
  • reporting

聚合與繼承的關系

從上面可以看到多模塊 Maven 項目中的聚合與繼承其實是兩個概念,其目的是完全不同的。聚合是為了方便快速構建項目,繼承是為了消除重復配置。

對於聚合模塊來說,它知道哪些被聚合的模塊(通過modules元素),但那些被聚合的模塊不知道這個聚合模塊的存在。

對於繼承關系的父 POM 來說,它不知道哪些子模塊繼承於它,但那些子模塊都必須知道自己的父 POM 是什么。

在實際項目中,大家會發現一個 pom 即是聚合 pom,又是父 pom,這么做主要是為了方便。就像上面我們定義的聚合模塊為 taobao-aggregator,父級模塊為 taobao-parent,我們可以將其合並成為一個名為 taobao 的 pom 文件。這樣清晰明了。

總結

如果看完本文還是不理解,那么可以自己去看下《Maven實戰》中關於聚合和繼承的講解,里面講得更加細致。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM