Maven學習(五)-- 聚合與繼承


標簽(空格分隔): 學習筆記


Maven的聚合特性能夠把項目的各個模塊聚合在一起構建;
Maven的繼承特性能夠幫助抽取各模塊相同的依賴和插件等配置,在簡化POM的同時,還能夠促進各個模塊配置的一致性。

account-persist模塊

POM文件

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.park.mvnDemo.account</groupId>
    <artifactId>account-persist</artifact>
    <name>Account Persist</name>
    <version>1.0.0-SNAPSHOT</version>
    
    <dependencies>  
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifact>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifact>
            <version>2.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifact>
            <version>2.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifact>
            <version>2.5.6</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifact>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
                <filtering>true</filtering>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

account-persist模塊還需要一個SpringFramework的配置文件,位於src/main/resources目錄:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
    <bean id="propertyConfigure" class="org.springframework.beans.factory.config.PropertyPlaceholderconfigure">
        <property name="location" value="classpath:account-service.properties"/>
    </bean>
    
    <bean id="accountPersistService" class="com.park.mvnDemo.account.persist.AccountPersistServiceImpl">
    <property name="file" value="${persist.file}"/>
    </bean>
<beans>

聚合

我們想要一次構建兩個項目,而不是到兩個模塊的目錄下分別執行mvn命令 -- Maven的聚合就是為該需求服務的。

為了能夠使用一條命令就能構建account-emailaccount-persist兩個模塊,需要創建一個額外的名為account-aggregator的模塊,然后通過該模塊構建整個項目的所有模塊。

account-aggregator也有它自己的POM文件,內容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org.maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.park.mvnDemo.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>

在上面的xml文件中,packaging的方式為pom。對於聚合模塊來說,其打包方式必須為pom,否則無法構建!

  • modules: 這里是實現聚合的最核心的配置,可以聲明任意數量的module元素來實現元素的聚合;
  • 其中,每個module的值為當前POM的相對路徑;
  • 如:當前POM位於D:\m2\code\account-aggregator\pom.xml, 另有一個項目A位於D:\m2\code\account-aggregator\account-email/,一個項目B位於D:\m2\code\-aggregatoraccount\account-persist/,與上面的module值相對應。
  • 為了方便用戶構建項目,通常將聚合模塊放在項目目錄的最頂層,其他模塊則作為聚合模塊的子目錄存在。

繼承

在我們已經聚合的項目中,有很多重復的配置,有相同的groupId和version,有相同的spring-core, spring-beans, spring-context和juit依賴,造成大量的浪費也會引發問題,所以如何使用繼承機制來統一配置這些重復的信息,做到”一處聲明,處處使用“呢?

思路:創建POM的父子結構,在父POM中聲明一些配置供子POM繼承、

父模塊

account-aggregator目錄下創建POM的父目錄account-parent,內部的pom文件內容為:

<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org.maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.park.mvnDemo.account</groupId>
    <artifactId>account-parent</artifactId>
    <version>1.0.0</version>
    <packaging>dom<packaging>
    <name>Account Parent</name>
</project>

作為父模塊的POM,其打包類型也是只能為pom。

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

子模塊 -- account-email

<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org.maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>com.park.mvnDemo.account</groupId>
        <artifactId>account-parent</artifactId>
        <version>1.0.0</version>
        <relativePath>../account-parent/pom.xml</relativePath>
    </parent>
    
    <artifactId>account-email</artifactId>
    <name>Account Email</name>
    
    <dependencies>
    ...
    </dependencies>
    
    <build>
        <plugins>
        ...
        </plugins>
    </build>
</project>

(子模塊account-persist的pom配置與之類似,不再贅述)

聚合模塊 -- account-aggregator

<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org.maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.park.mvnDemo.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>dom</packaging>
    <name>Account Aggregator</name>
    <modules>
        <module>account-parent</module>
        <module>account-email</module>
        <module>account-persist</module>
    </modules>
</project>

可繼承的POM元素

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

依賴管理

dependencies可以使得子模塊繼承父模塊依賴的插件,同時dependencyManagement元素又能保證子模塊使用的靈活性。在dependencyManagement元素下的聲明不會引入實際的依賴,不過它能夠約束dependencies下的依賴使用。
示例:

(一) 在account-parent中配置dependencyManagement元素

<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org.maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.park.mvnDemo.account</groupId>
    <artifactId>account-parent</artifactId>
    <version>1.0.0_SNAPSHOT</version>
    <packaging>dom</packaging>
    <name>Account Parent</name>
    <properties>
        <springframework.version>2.5.6</springframework.version>
        <junit.version>4.7</junit.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifact>
                <version>${springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </depedencyManagement>
</project>

(二) 繼承了dependencyManagement的account-email POM

<properties>
    <javax.mail.version>1.4.1</javax.mail.version>
    <greenmail.version>1.3.1b</greenmail.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>${javax.mail.version}</version>
    </dependency>
    <dependency>
        <groupId>com.icegreen</groupId>
        <artifactId>greenmail</artifactId>
        <version>${greenmail.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

如果不聲明某個依賴,那這個依賴就不會被引入。

插件管理

Maven提供了pluginManagement元素來管理插件。在該元素中配置的依賴不會造成實際的插件調用行為,當POM中配置了真正的plugin元素,並且其groupId和artifactId與pluginManagement中配置的插件相匹配時,pluginManagement的配置才會影響實際的插件行為。

(一) 在父POM中配置pluginManagement

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.1.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>verify<phase>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </exeuction>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

(二) 在子模塊中配置相應的插件

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

聚合與繼承的關系

  • 聚合是為了方便快速構件項目。對於聚合模塊來說,它知道有哪些被聚合的模塊,但那些模塊不知道這個聚合模塊的存在;
  • 繼承是為了消除重復配置。對於繼承關系的父POM來說,它不知道有哪些子模塊繼承於它,但是子模塊必須知道自己的父POM是什么。

在實際的項目中,一個POM可以既是聚合POM,又是父POM。
如果父模塊位於子模塊們的上級,則不需要再額外配置relativePath,因為Maven默認能識別父模塊的位置。

反應堆(Reactor)

在一個多模塊的Maven項目中,反應堆是指所有模塊組成的一個構件結構。包含了各模塊之間繼承於依賴的關系,從而能夠自動計算出合理的模塊構件順序。

Maven實際的構建順序是:Maven按序讀取POM,如果該POM沒有依賴模塊,那么就構建該模塊,否則就先構建其依賴模塊,如果該依賴模塊還依賴於其他模塊,則進一步先構建其他模塊。

模塊間的依賴關系會將反應堆構成一個有向無環圖(DAG: Directed Acyclic Graph),各個模塊是該圖的節點,依賴關系構成了有向邊。

裁剪反應堆

當用戶並不想構建整個項目的時候,就需要實時地裁剪反應堆。
Maven提供很多命令行支持裁剪反應堆:

  • -am, --alsomake: 同時構建所列模塊的依賴模塊模塊;

  • -amd, --also-make-dependents: 同時構建依賴於所列模塊的模塊;

  • -pl, --projects<arg>: 構建指定模塊,模塊間用逗號分割;

  • -rf, -resume-from<arg>: 從指定的模塊回復反應堆。

    $ mvn clean install
    \\Output: Account Aggregator, Account Parent, Account Email, Account Persist
    $ mvn clean install -pl account-email,account-persist
    \\Output: Account Email, Account Persist
    $ mvn clean install -pl account-email -am
    \\Output: Account Parent, Account Email
    $ mvn clean install -pl account-parent -amd
    \\Output: Account Parent, Account Email, Account Persist
    $ mvn clean install -rf account-email
    \\Output: Account Email, Account Persist
    $ mvn clean install -pl account-parent -amd -rf account-email
    \\Output: Account Email, Account Persist


免責聲明!

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



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