maven_05_聚合與繼承

一、前言

在進行項目開發時,我們通常會對項目進行模塊化劃分,這樣一個項目被劃分爲多個模塊。

二、聚合

通過聚合,我們可以一次構建多個模塊。

1.佈局方式

聚合模塊通常是一個POM工程,項目佈局方式有兩種:分層佈局和水平佈局

1.1 分層佈局

在這裏插入圖片描述

<project>  
    <modelVersion>4.0.0</modelVersion>  
   
    <groupId>com.juvenxu.mvnbook.account</groupId>  
    <artifactId>account-aggregator</artifactId>  
    <version>1.0.0-SNAPSHOT</version>  
    <packaging> pom </packaging>  

    <name>Account Aggregator</name> 
     
    <modules>  
        <module>account-email</module>  
        <module>account-persist</module>  
    </modules>  
</project>

在POM工程下,通過 module元素可以聲明此POM所包含的模塊

1.2 水平佈局

在這裏插入圖片描述

<project>  
    <modelVersion>4.0.0</modelVersion>  
   
    <groupId>com.juvenxu.mvnbook.account</groupId>  
    <artifactId>account-aggregator</artifactId>  
    <version>1.0.0-SNAPSHOT</version>  
    <packaging> pom </packaging>  

    <name>Account Aggregator</name> 
     
    <modules>  
        <module>../account-email</module>  
        <module>../account-persist</module>  
    </modules>  
</project>

2.項目構建過程

若在聚合模塊下執行 mvn clean install , 則項目構建過程:

  • 首先解析聚合模塊的POM、分析要構建的模塊、並計算出一個反應堆構建順序(ReactorBuildOrder)
  • 然後根據這個順序依次構建各個模塊。

反應堆是所有模塊組成的一個構建結構。

三、繼承

Maven的繼承與JAVA中的繼承,思想一致。

通過聚合,我們可以使用一條命令構建多個模塊。然而多模塊下,還會存在依賴、插件重複定義的問題,而這可以通過繼承來解決。

通過繼承,我們可以集中管理整個項目下多個模塊依賴、插件的版本以及項目的GroupId,一定程度上消除重複。

1.聲明繼承

1.1 父POM

父POM模塊需要聲明爲一個POM工程,來供子模塊繼承

<project>  
    <modelVersion>4.0.0</modelVersion>  
    
    <groupId>com.juvenxu.mvnbook.account</groupId>  
    <artifactId> account-parent </artifactId>  
    <version>1.0.0-SNAPSHOT</version>  
    <packaging>pom</packaging>  
    <name>Account Parent</name>  
    
</project>

在實際項目中,一個POM工程,既可以是聚合POM ,又可以是父POM

1.2 子模塊

<project>  
    <modelVersion>4.0.0</modelVersion>  
      
    < parent >  
        <groupId>com.juvenxu.mvnbook.account</groupId>  
        <artifactId> account-parent </artifactId>  
        <version>1.0.0-SNAPSHOT</version>  
        < relativePath >../account-parent/pom.xml</ relativePath>  
    </ parent >  
      
    <artifactId> account-email </artifactId>  
    <name>Account Email</name>  
  ...  
</project>
  • parent : 父模塊
  • relativePath :父模塊POM的相對路徑

當項目構建時,Maven會首先根據relativePath檢查父POM,如果找不到,再從本地倉庫查找。

relativePath的默認值是…/pom.xml,也就是說,Maven默認父POM在上一層目錄下(分層佈局)。

子模塊隱式地從父模塊繼承 groupIdversion這兩個元素,

2.可繼承的POM元素

元素 含義
groupId 項目組 ID ,項目座標的核心元素
version 項目版本,項目座標的核心元素
description 項目的描述信息
organization 項目的組織信息
inceptionYear 項目的創始年份
url 項目的 url 地址
developers 項目的開發者信息
contributors 項目的貢獻者信息
distributionManagerment 項目的部署信息
issueManagement 缺陷跟蹤系統信息
ciManagement 項目的持續繼承信息
scm 項目的版本控制信息
mailingLists 項目的郵件列表信息
properties 自定義的 Maven 屬性
dependencies 項目的依賴配置
dependencyManagement 醒目的依賴管理配置
repositories 項目的倉庫配置
build 包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等
reporting 包括項目的報告輸出目錄配置、報告插件配置等

3.依賴管理

  • 在父POM中 使用 dependencyManagement 元素來聲明依賴,並統一管理依賴的版本

  • 子模塊使用這些依賴時就無需聲明版本

dependencyManagement 元素中只是對依賴進行聲明,而並未真正使用依賴。要使用依賴需要藉助根元素project下的dependencies元素。

3.1 父POM依賴管理

<project>  
    <modelVersion>4.0.0</modelVersion>  
    
    <groupId>com.juvenxu.mvnbook.account</groupId>  
    <artifactId> account-parent </artifactId>  
    <version>1.0.0-SNAPSHOT</version>  
    <packaging>pom</packaging>  
    <name>Account Parent</name>  
    
    <properties>
        <jackson.version>2.8.8</jackson.version>
    </properties>

    <dependencyManagement>
        <dependencies>
                <!-- jackson -->
                <dependency>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-core</artifactId>
                    <version>${jackson.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-databind</artifactId>
                    <version>${jackson.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-annotations</artifactId>
                    <version>${jackson.version}</version>
                </dependency>
        </dependencies>
    </dependencyManagement>
</project>

3.2 子模塊使用依賴

子模塊可繼承父模塊聲明的依賴信息,使用父模塊聲明的依賴時無需依賴的聲明版本

<project>  
    <modelVersion>4.0.0</modelVersion>  
      
    < parent >  
        <groupId>com.juvenxu.mvnbook.account</groupId>  
        <artifactId> account-parent </artifactId>  
        <version>1.0.0-SNAPSHOT</version>  
        < relativePath >../account-parent/pom.xml</ relativePath>  
    </ parent >  
      
    <artifactId> account-email </artifactId>  
    <name>Account Email</name>  

    <dependencies>
        <!-- jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>
    </dependencies>
    
</project>

4.插件管理

使用元素可以

  • 在父POM中 使用 pluginManagement 元素來聲明插件以及插件的行爲
  • 子模塊使用這些插件時就無需聲明版本以及定義行爲了

在該元素中配置的依賴不會造成實際的插件調用行爲,當POM中配置了真正的 plugin元素,並且其 groupId和 artifactId與 pluginManagement中配置的插件匹配時, pluginManagement的配置纔會影響實際的插件行爲.

4.1 父POM插件管理

當項目中的多個模塊有同樣的插件配置時,應當將配置移到父POM的 pluginManagement 元素中。

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.6.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.18.1</version>
                    <configuration>
                        <skipTests>true</skipTests>
                    </configuration>
                </plugin>
                <plugin>
                    <!-- if including source jars, use the no-fork goals
                         otherwise both the Groovy sources and Java stub sources
                         will get included in your jar -->
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <!-- source plugin \> = 2.1 is required to use the no-fork goals -->
                    <version>2.4</version>
                    <executions>
                        <execution>
                            <id>attach-sources</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>jar-no-fork</goal>
                                <goal>test-jar-no-fork</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
  • maven-compiler-plugin :針對 compile 生命週期,指定源碼和輸出class的java版本,以及字符編碼

  • maven-surefire-plugin : 針對 test 生命週期,指定跳過單元測試

  • maven-source-plugin :針對 verity 生命週期,指定生成項目源碼包

4.2 子模塊使用插件

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 若子模塊需要使用父POM中聲明的插件,則可以直接使用 groupIdartifactId來引用。

  • 若子模塊需要不同配置的插件,則可以自行配置以覆蓋父POM所聲明的配置。

  • 若子模塊不需要父POM聲明的插件,忽略即可。

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 若子模塊需要使用父POM中聲明的插件,則可以直接使用 groupIdartifactId來引用。

  • 若子模塊需要不同配置的插件,則可以自行配置以覆蓋父POM所聲明的配置。

  • 若子模塊不需要父POM聲明的插件,忽略即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章