1、聚合
Maven聚合(或者稱爲多模塊),是爲了能夠使用一條命令就構建多個模塊,例如已經有兩個模塊,分別爲account-email,account-persist,我們需要創建一個額外的模塊(假設名字爲account-aggregator,然後通過該模塊,來構建整個項目的所有模塊,accout-aggregator本身作爲一個Maven項目,它必須有自己的POM,不過作爲一個聚合項目,其POM又有特殊的地方,看下面的配置:
<project
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.juvenxu.mvnbook.account</groupId>
<artifact>account-aggregator</artifact>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Aggregator</name>
<modules>
<module>account-email</module>
<module>account-persist</module>
</modules>
</project>
上面有一個特殊的地方就是packaging,其值爲pom,如果沒有聲明的話,默認爲jar,==對於聚合模塊來說,其打包方式必須爲pom==,否則無法構建。
modules裏的每一個module都可以用來指定一個被聚合模塊,這裏每個module的值都是一個當前pom的相對位置,本例中account-email、account-persist位於account-aggregator目錄下,當三個項目同級的時候,上面的兩個module應該分別爲../account-email和../account-persist
2、繼承
在構建多個模塊的時候,往往會多有模塊有相同的groupId、version,或者有相同的依賴,例如:spring-core、spring-beans、spring-context和junit等,或者有相同的組件配置,例如:maven-compiler-plugin和maven-resources-plugin配置,在Maven中也有類似Java的繼承機制,那就是POM的繼承。
繼承POM的用法
面向對象設計中,程序員可以通過一種類的父子結構,在父類中聲明一些字段和方法供子類繼承,這樣可以做到“一處聲明、多處使用”,類似的我們需要創建POM的父子結構,然後在父POM中聲明一些配置,供子POM繼承。
下面聲明一個父POM,如下:
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:shemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<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中,groupId和version和其它模塊一樣,它的packaging爲pom,這一點和聚合模塊一樣,==作爲父模塊的POM,其打包類型也必須爲pom==,由於父模塊只是爲了幫助消除配置的重複,因此它本身不包含除POM之外的項目文件,也就不需要src/main/java之類的文件夾了。
有了父模塊,就需要其它模塊來繼承它。首先將account-email的POM修改如下:
account-email繼承account-parent的POM
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:shemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<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>
....
</dependencies>
<build>
<plugins>
....
</plugins>
</build>
</project>
上面POM中使用parent元素聲明父模塊,==paren下的子元素groupId、artifactId和version指定了父模塊的座標,這三個元素是必須的==。元素relativePath表示了父模塊POM的相對位置。當項目構建時,Maven會首先根據relativePath檢查父POM,如果找不到,再從本地倉庫查找。relativePath的默認值是../pom.xml,Maven默認父POM在上一層目錄下。
上面POM沒有爲account-email聲明groupId,version,不過並不代表account-email沒有groupId和version,實際上,這個子模塊隱式的從父模塊繼承了這兩個元素,這也就消除了不必要的配置。上例中,父子模塊使用了相同的groupId和version,如果遇到子模塊需要使用和父模塊不一樣的groupId或者version的情況,可以在子模塊中顯式聲明。對於artifactId元素來說,子模塊更應該顯式聲明,因爲如果完全繼承groupId、artifactId、version,會造成座標衝突;另一方面,即使使用不同的groupId或version,同樣的artifactId容易造成混淆。
account-persist繼承account-parent的POM
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:shemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<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-persist</artifactId>
<name>Account Persist</name>
<dependencies>
....
</dependencies>
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
<plugins>
....
</plugins>
</build>
</project>
最後,同樣需要把account-parent加入到聚合模塊accountp-aggregator中,代碼如下:
將account-parent加入到聚合模塊
<project
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.juvenxu.mvnbook.account</groupId>
<artifact>account-aggregator</artifact>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Aggregator</name>
<modules>
<module>account-email</module>
<module>account-persist</module>
<module>account-parent</module>
</modules>
</project>
可繼承的POM元素
- groupId:項目組ID,項目座標的核心元素
- version:項目版本,項目座標的核心元素
- description:項目的描述信息
- organnization:項目的組織信息
- inceptionYear:項目的創始年份
- url:項目的URL地址
- developers:項目的開發者信息
- contributors:項目的貢獻者信息
- distributionManagement:項目的部署配置
- issueManagement:項目的缺陷跟蹤系統信息
- ciManagement:項目的集成信息
- scm:項目的版本控制系統信息
- mailingLists:項目的郵件列表信息
- properties:自定義的Maven屬性
- dependencies:項目的依賴配置
- dependencyManagement:項目的依賴管理配置
- repositories:項目的倉庫配置
- build:包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等
- reporting:包括項目的報告輸出目錄配置,報告插件配置等。
依賴管理
當多有模塊中有相同的依賴時,我們可以將這些依賴提取出來,統一在父POM中聲明,這樣就可以簡化子模塊的配置了,但是這樣還是存在問題,當想項目中加入一些,不需要這麼多依賴的模塊,如果讓這個模塊也依賴那些不需要的依賴,顯然不合理。
Maven提供的dependentcyManagement元素既能讓子模塊繼承到父模塊的依賴配置,又能保證子模塊依賴使用的靈活度。在dependentcyManagement元素下的依賴聲明不會引入實際的依賴,不過他能夠約束denpendencies下的依賴使用。對上面的accoun-parent進行改進,代碼如下:
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:shemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<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>
<springframework.version>2.5.6</springframework.version>
<junit.version>4.7</junit.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<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>${springframework.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
上面使用了dependencyManagement聲明的依賴既不會給account-parent引入依賴,也不會給它的子模塊引入依賴,不過這段配置是會被繼承的。
修改account-email的POM如下:
繼承dependencyManagement的account-email POM
<properties>
<javax.mail.version>1.4.1</javax.mail.version>
<greenmail.version>1.3.1b</greenmail.version>
</properties>
<dependencyManagement>
<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>javax.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>${greenmail.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
子模塊只需要配置簡單的groupId和artifactId就能獲得對應的依賴信息,從而引入正確的依賴。
這種依賴管理機制似乎不能減少太多的POM配置,但是其好處很大,原因在於在POM中使用dependencyManagement聲明依賴能夠統一規範項目中依賴的版本,當依賴的版本在父POM中聲明之後,子模塊在使用依賴的時候就無效聲明版本,也就不會發生多個子模塊使用依賴版本不一致的情況。這可以降低依賴衝突的機率。
如果在子模塊不聲明依賴的使用,即使該依賴已經在父POM的dependencyManagement中聲明瞭,也不會產生任何實際的效果。
如果子模塊不聲明依賴的使用,即使該依賴已經在父POM的dependencyManagement中聲明瞭,也不會產生任何實際的效果,如account-persist的POM。
<properties>
<dom4j.version>1.6.1</dom4j.version>
</properties>
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>dom4j.version</version>
</dependency>
<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>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
這裏沒有聲明spring-context-support,那麼該依賴就不會被引入。這正是dependencyManagement的靈活性所在
- 另外,依賴範圍有個import範圍,import依賴範圍只有在dependencyManagement下才有效果,使用該範圍的依賴通常指向一個POM,作用是將目標中的dependencyManagement配置導入到當前POM的dependencyManagement中配置,除了複製配置或者繼承這兩種方式之外,還可以使用import範圍依賴將這一配置導入。
使用import範圍依賴導入依賴管理配置
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.juvenxu.mvnbook.account<groupId>
<artifactId>account-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
注意,上面代碼中依賴的type爲pom,import依賴範圍由於其特殊性,一般都指向打包類型爲pom的模塊。如果有多個項目,他們使用的依賴版本都是一致的,則可以定義一個dependencyManagement專門管理依賴的POM,然後在各個項目中導入這些依賴管理配置。
插件管理
Maven提供了dependencyManagement元素幫忙管理依賴,類似地,Maven也提供了pluginManagement元素幫忙管理插件。該元素中配置的依賴不會造成實際的插件調用行爲,當POM中配置了真正的plugin元素,並且其groupId和artifactId與pluginManagement中配置的插件匹配時,pluginManagement的配置纔會影響實際的插件行爲。
前面有如何通過組件去將jar-no-fork目標綁定到verity生命週期階段,以生成項目源碼包。如果一個項目中有很多子模塊,並且需要這些模塊的源碼包,那麼很顯然,爲所有模塊重複類似的插件配置不是最好的辦法,這時最好的辦法是在父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>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
當子模塊需要生成源碼包的時候,只需要如下簡單的配置,代碼如下:
子模塊聲明使用了maven-source-plugin插件,同時又繼承了父模塊的pluginManagement配置,兩者基於groupId和artifactId匹配合並。
有了pluginManagement元素,accout-email和accout-persist的POM也能得以簡化了他們都配置了maven-compiler-plugin和maven-resources-plugin。可以將這兩個插件的配置移到account-parent的pluginManagement元素中,代碼如下:
<build>
<pluginMangement>
<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>
<artifact>maven-resources-plugin</artifact>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginMangement>
</build>
accout-email和account-persist可以完全地移除關於maven-compiler-plugin和maven-resources-plugin的配置,但他們仍然能享受這這個插件的服務,前一插件開啓了jdk1.5編譯的支持,後一插件也會使用UTF-8編碼處理資源文件。這背後涉及了很多Maven機制,首先,內置的插件綁定關係將兩個插件綁定到了account-email和account-persist生命週期上,其次,超級POM爲這兩個插件申明瞭版本;最後,account-parent中的pluginManagement對這兩個插件的行爲進行了配置。
當項目中的多個模塊有同樣的插件配置時,應當將配置移到父POM的pluginMangement元素中。即使各個模塊對於同一插件的具體配置不盡相同,也應當使用父POM的pluginManagement元素同意聲明插件的版本。甚至可以要求將所有用到的插件的版本在父POM的pluginManagement中聲明,子模塊使用插件時不配置版本信息,這麼做可以統一項目的插件版本,避免潛在的插件不一致或者不穩定的問題,也更易於維護。
3、聚合與繼承的關係
多模塊中的聚合與繼承其實是兩個概念,其目的是完全不同的,前者主要是爲了方便快速構建項目,後者主要是爲了消除重複配置。
對於聚合模塊來說,它知道有哪些被聚合的模塊,但那些被聚合的子模塊不知道這個聚合模塊的存在。
對於繼承關係的父POM來說,它不知道哪些子模塊繼承於它,但那些子模塊都必須知道自己的父POM是什麼。
聚合關係與繼承關係的比較
在現有的實際項目中,往往會發現一個POM既是聚合POM,又是父POM,這麼做主要是爲了方便。一般來說,融合使用聚合與繼承也沒什麼問題,例如可以將account-aggretor和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.juvenxu.mvnbook.account</groupId>
<artifactId>account-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Parent</name>
<modules>
<module>account-persist</module>
</modules>
<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</artifactId>
<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>
</dependencyManagement>
<build>
<pluginManagement>
<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-resource-plugin<artifactId>
<configuration>
<endcoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build
</project>
可以看到POM的打包方式爲pom,它包含了一個modules元素,表示用來聚合account-persist和account-email兩個模塊,它還包含了properties、dependencyManagement和pluginManagement元素供子模塊繼承。
4、約定優於配置
Maven默認的源碼目錄是:src/main/java但是用戶也可以自己指定源碼目錄,如下:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook<groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
<build>
<sourceDirectory>src/java</sourceDirectory>
</build>
</project>
上面配置就將源碼目錄改爲src/java而不是默認的src/main/java
任何一個Maven項目都隱式的繼承自該POM,這有點類似任何一個Java類都隱式的繼承於Object類,因此,大量超級POM的配置都會被所有Maven項目繼承,這些配置也就成爲了Maven所提倡的約定。
對於Maven3,超級POM在文件$MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路徑下。對於Maven2,超級POM在文件$MAVEN_HOME/lib/maven-x.x.x-uber.jar中的org/apache/maven/project/pom-4.0.0.xml目錄下。
超級POM的內容在Maven2和Maven3中基本一致,分段看一下,見代碼:
<repositories>
<repository>
<id>central</id>
<name>Maven Repository Switchboard</name>
<url>http://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
超級POM定義了倉庫及插件倉庫,兩者的地址都是爲中央倉庫http://repo1.maven.org/maven2,並且都關閉了SNAPSHOT的支持,這也就解釋了爲什麼Maven默認就可以按需要從中央倉庫下載構件。
超級POM中關於項目結構的定義:
<build>
<directory>${project.basedir}/target<directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>src/main/script</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
這裏依次定義了項目的主輸出目錄,主代碼輸出目錄,最終構件的名稱格式、測試代碼輸出格式、主源碼目錄,腳本源碼目錄、測試源碼目錄、主資源目錄和測試資源目錄。這就是Maven項目結構的約定。
接着,超級POM爲核心差勁設定版本,代碼如下:
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-bete-4</version>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.3</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
</plugin>
........
</plugins>
</pluginManagement>
</build>
5、反應堆
在一個多模塊的Maven項目中,反應堆(Reactor)是指所有模塊組成的一個構建結構。對於單模塊的項目,反應堆就是該模塊本身,對於多模塊來說,反應堆就包含了各模塊之間繼承與依賴的關係,從而能夠自動計算出合理的模塊構建順序。
例如修改account-aggregator的聚合配置:
<modules>
<module>account-email</module>
<module>account-persist</module>
<module>account-parent</module>
</modules>
構建account-aggregator,會看到如下輸出:
[INFO] -----------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Account Aggregator
[INFO] Account Parent
[INFO] Account Email
[INFO] Account Persist
[INFO]
[INFO] -----------------------------------------
以上,構建順序不一定是順序去讀取POM的順序。當一個模塊依賴於另外一個模塊,Maven會先去構建被依賴模塊,如果被依賴的模塊還依賴其他模塊,則進一步先構建依賴的依賴。
賬戶註冊服務4個模塊的反應堆
從上到下的箭頭表示pom的讀取次序,從右至左的箭頭表示模塊之間的繼承或者依賴。模塊間的依賴(泛指依賴或者繼承)關係會將反應堆構成一個有向非循環圖(Directed Acyclic Graph,DGA),各個模塊是該圖的節點,依賴關係構成有向邊。這個圖不允許出現循環,因此,當出現模塊A依賴於B,而B又依賴於A的情況時,Maven就會報錯。
裁剪反應堆
一般來說,用戶會選擇構建整個項目或者選擇構建單個的模塊,但有些時候,用戶會想要僅僅構建完整反應堆中的某些個模塊。換句話說,用戶需要實時地剪裁反應堆。
Maven提供很多命令行選項支持裁剪反應堆,輸入mvn -h可以看到這些選項:
- -am, --also-make 同時構建所列模塊的依賴模塊
- -amd -also-make-dependents 同時構建依賴於所列模塊的模塊
- -pl,--project <arg> 構建指定的模塊,模塊間用逗號分隔
- -rf -resume-from <arg> 從指定的模塊回覆反應堆
默認情況從account-aggregator執行mvn clean install會得到如下完整的反應堆:
[INFO]-----------------------------------------------------
[INFO]Reactor Build Order:
[INFO]
[INFO]Account Aggregator
[INFO]Account Parent
[INFO]Account Email
[INFO]Account Persist
[INFO]
[INFO]-----------------------------------------------------
可以使用-pl選項指定構建某幾個模塊,如運行如下命令:
$ mvn clean install -pl account-email,account-persist
得到的反應堆爲:
[INFO]-----------------------------------------------------
[INFO]Reactor Build Order:
[INFO]
[INFO]Account Email
[INFO]Account Persist
[INFO]
[INFO]-----------------------------------------------------
使用-am選項可以同時構建所列模塊的依賴模塊,例如:
$ mvn clean install -pl account-email -am
由於account-email依賴於account-parent,因此會得到如下反應堆:
[INFO]-----------------------------------------------------
[INFO]Reactor Build Order:
[INFO]
[INFO]Account Parent
[INFO]Account Email
[INFO]
[INFO]-----------------------------------------------------
使用-amd選項可以同時構建依賴於所列模塊的模塊。例如:
$ mvn clean install -pl account-parent -amd
由於account-email和account-persist都賴於account-parent,因此會得到如下反應堆:
[INFO]-----------------------------------------------------
[INFO]Reactor Build Order:
[INFO]
[INFO]Account Parent
[INFO]Account Email
[INFO]Account Persist
[INFO]
[INFO]-----------------------------------------------------
使用-rf選項可以在完整的反應堆構建順序基礎上指定從哪個模塊開始構建。例如:
$mvn clean install -rf account-email
完整的反應堆構建順序中,account-email位於第三,它之後只有account-persist因此會得到如下的剪裁反應堆:
[INFO]-----------------------------------------------------
[INFO]Reactor Build Order:
[INFO]
[INFO]Account Email
[INFO]Account Persist
[INFO]
[INFO]-----------------------------------------------------
最後在-pl -am或者-pl -amd的基礎上,還能應用-rf參數,以對裁剪後的反應堆再次剪裁,例如:
$ mvn clean install -pl account-parent -amd -rf account-email
該命令中的-pl和-amd參數會裁剪出一個account-parent、account-email和account-persist的反應堆,在此基礎上,-rf參數指定從account-email參數構建。因此會得到如下的反應堆:
[INFO]-----------------------------------------------------
[INFO]Reactor Build Order:
[INFO]
[INFO]Account Email
[INFO]Account Persist
[INFO]
[INFO]-----------------------------------------------------
在開發過程中,靈活應用上述四個參數,可以幫助我們跳過無須構建的模塊,從而加速構建。在項目龐大、規模特別多的時候,這種效果就會異常明顯。