項目的繼承和聚合詳解


 

一、聚合與繼承的關系

聚合主要為了快速構建項目,繼承主要為了消除重復

二、為什么要聚合?

隨着技術的飛速發展和各類用戶對軟件的要求越來越高,軟件本身也變得越來越復雜,然后軟件設計人員開始采用各種方式進行開發,於是就有了我們的分層架構、分模塊開發,來提高代碼的清晰和重用。針對於這一特性,maven也給予了相應的配置。

情景分析一:

我們在開發過程中,創建了2個以上的模塊,每個模塊都是一個獨立的maven project,在開始的時候我們可以獨立的編譯和測試運行每個模塊,但是隨着項目的不斷變大和復雜化,我們期望能夠使用簡單的操作來完成編譯等工作,這時Maven給出了聚合的配置方式。

所謂聚合,顧名思義,就是把多個模塊或項目聚合到一起,我們可以建立一個專門負責聚合工作的Maven project ---  aggregator。

建立該project的時候,我們要注意以下幾點:

1.該aggregator本身也做為一個Maven項目,它必須有自己的POM

2.它的打包方式必須為: pom

3.引入了新的元素:modules---module

4.版本:聚合模塊的版本和被聚合模塊版本一致

5.relative path:每個module的值都是一個當前POM的相對目錄

6.目錄名稱:為了方便的快速定位內容,模塊所處的目錄應當與其artifactId一致(Maven約定而不是硬性要求),總之,模塊所處的目錄必須和<module>模塊所處的目錄</module>相一致。

7.習慣約定:為了方便構建,通常將聚合模塊放在項目目錄層的最頂層,其它聚合模塊作為子目錄存在。這樣當我們打開項目的時候,第一個看到的就是聚合模塊的POM

8.聚合模塊減少的內容:聚合模塊的內容僅僅是一個pom.xml文件,它不包含src/main/java、src/test/java等目錄,因為它只是用來幫助其它模塊構建的工具,本身並沒有實質的內容。

9.聚合模塊和子模塊的目錄:他們可以是父子類,也可以是平行結構,當然如果使用平行結構,那么聚合模塊的POM也需要做出相應的更改。
三、為什么要繼承?

做面向對象編程的人都會覺得這是一個沒意義的問題,是的,繼承就是避免重復,maven的繼承也是這樣,它還有一個好處就是讓項目更加安全

情景分析二:我們在項目開發的過程中,可能多個模塊獨立開發,但是多個模塊可能依賴相同的元素,比如說每個模塊都需要Junit,使用spring的時候,其核心jar也必須都被引入,在編譯的時候,maven-compiler-plugin插件也要被引入

如何配置繼承:

1.說到繼承肯定是一個父子結構,那么我們在aggregator中來創建一個parent project

2.<packaging>: 作為父模塊的POM,其打包類型也必須為POM

3.結構:父模塊只是為了幫助我們消除重復,所以它也不需要src/main/java、src/test/java等目錄

4.新的元素:<parent> , 它是被用在子模塊中的

5.<parent>元素的屬性:<relativePath>: 表示父模塊POM的相對路徑,在構建的時候,Maven會先根據relativePath檢查父POM,如果找不到,再從本地倉庫查找

6.relativePath的默認值: ../pom.xml

7.子模塊省略groupId和version: 使用了繼承的子模塊中可以不聲明groupId和version, 子模塊將隱式的繼承父模塊的這兩個元素
8.dependencyManagement聲明依賴可以統一項目中依賴的版本。如果子類模塊不聲明依賴的使用,也不會產生任何效果。

可被繼承的POM元素


groupId:項目組ID,項目坐標的核心元素

version: 項目版本, 項目坐標的核心元素

description: 項目的描述信息

organization: 項目的組織信息

inceptionYear: 項目的創始年份

url: 項目的URL地址

developers: 項目開發者信息

contributors: 項目的貢獻者信息

distributionManagement: 項目的部署配置

issueManagement: 項目的缺陷跟蹤系統信息

ciManagement: 項目的持續集成系統信息

scm: 項目的版本控制系統信息

mailingLists: 項目的郵件列表信息

properties: 自定義的maven屬性

dependencies: 項目的依賴配置

dependencyManagement: 項目的依賴管理配置

repositories: 項目的倉庫配置

build: 包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等

reporting: 包括項目的報告輸出目錄配置、報告插件配置等

maven的依賴管理

我們知道dependencies是可以被繼承的,這個時候我們就想到讓我們的發生了共用的依賴元素轉移到parent中,這樣我們又進一步的優化了配置。可是問題也隨之而來,如果有一天我創建了一個新的模塊,但是這個模塊不需要這些parent的依賴,這時候如何處理?

是的,maven的依賴管理就是來解決這個問題的

增加一個新的元素:dependencyManagement

從上面的列表中我們發現dependencyManagement也是可以被繼承的,這恰恰滿足了我們的需要,它既能夠讓子模塊繼承到父模塊的依賴配置,又能保證子模塊依賴使用的靈活性

dependencyManagement的特性:在dependencyManagement中配置的元素既不會給parent引入依賴,也不會給它的子模塊引入依賴,僅僅是它的配置是可繼承的

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

子模塊的POM繼承這些配置:子模塊繼承這些配置的時候,仍然要聲明groupId和artifactId,表示當前配置是繼承於父POM的,從而直接使用父POM的版本對應的資源

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

這個可以有效的避免多個子模塊使用依賴版本不一致的情況,有助於降低依賴沖突的幾率。注:只有子模塊配置了繼承的元素,才會真正的有效,否則maven是不會加載父模塊中聲明的元素。如果某個子項目需要另外一個版本號時,只需要在dependencies中聲明一個版本號即可。子類就會使用子類聲明的版本號,不繼承於父類版本號。 

區別

           dependencies即使在子項目中不寫該依賴項,那么子項目仍然會從父項目中繼承該依賴項(全部繼承)

         dependencyManagement里只是聲明依賴,並不實現引入,因此子項目需要顯示的聲明需要用的依賴。如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;只有在子項目中寫了該依賴項,並且沒有指定具體版本,才會從父項目中繼承該項,並且versionscope都讀取自父pom;另外如果子項目中指定了版本號,那么會使用子項目中指定的jar版本。 

         注意 ${project.version} 變量指的是應用的 version 。

         頂層 pom 中的 dependencies 與 dependencyManagement 中的 dependencies 元素有一個重要的區別:

dependencyManagement 中的 dependencies 元素只表明依賴項版本的優先選擇,並不影響項目的依賴項;而 dependencies 元素則影響項目的依賴項。

五、Maven的插件管理 

再增加一個新的元素:<pluginManagement> 

這個元素和<dependencyManagement>相類似,它是用來進行插件管理的。 

在我們項目開發的過程中,也會頻繁的引入插件,所以解決這些復雜配置的方法就是使用插件管理 

我們可以在父POM中做如下聲明:

<build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId></groupId>
                    <artifactId></artifactId>
                    <version></version>
                    <executions>
                        <execution>
                            <id></id>
                            <goals>
                                <goal></goal>
                            </goals>
                            <phase></phase>
                            <configuration>
                                <source></source>
                                <target></target>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

在子模塊中,我們可以直接繼承

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
        </plugins>
 </build>

我們會發現,繼承的細節上和<dependencyManagement>幾乎一樣。

四、聚合與繼承的總結

當我們明白聚合與繼承的細節之后,我們會發現:

對於聚合模塊來說,它知道有哪些被聚合的模塊,而對於被聚合的模塊來說,它們不知道被誰聚合了,也不知道它的存在

對於繼承關系的父POM來說,它不知道自己被哪些子模塊繼承了,對於子POM來說,它必須知道自己的父POM是誰

在一些最佳實踐中我們會發現:一個POM既是聚合POM,又是父POM,這么做主要是為了方便。

五.聚合模塊的創建

1.創建父模塊

 

2.創建多個子module

 注意此處為父子目錄結構,

xml中modules的書寫為

<modules>
      <module>bsv-api</module>
      <module>bsv-config</module>
  </modules>

 

如果是平行級目錄,則modules的書寫為

<modules>
      <module>../bsv-api</module>
      <module>../bsv-config</module>
  </modules>

注意如果新建的項目如果沒有任何類,也會導致構建失敗

 

 

 

六.繼承模塊的創建

1.父模塊的創建

新建maven工程

選擇site simple

或者

子模塊的創建

父類添加dependencyManagement依賴管理

<properties>
        <junit.version>4.12</junit.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

子類添加relativePath 正確設置relativePath的值非常重要,如果不正確,maven找不到父pin,構建失敗 默認值為../pom.xml

 <relativePath>../parentDemo/pom.xml</relativePath>

 

依賴的使用:可省去版本信息,單元測試scope也可省去。雖然這些不能減少太多的pom配置,但是還是強烈推薦,dependencyManagement聲明依賴可以統一項目中依賴的版本。如果子類模塊不聲明依賴的使用,也不會產生任何效果。

 <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

然后構建成功

最后

 5.import的依賴范圍

只在dependenceyManagement元素下才有用,想要使用和另外一模塊完全一樣的dependenceyManagement配置,除了復制配置,繼承兩種方式外還可以使用import范圍依賴將這一配置導入

 


免責聲明!

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



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