Maven的聚合特性能夠把項(xiàng)目的各個(gè)模塊聚合在一起構(gòu)建,而繼承特性則能夠幫助抽取各模塊相同的依賴和插件等配置,在簡(jiǎn)化POM的同時(shí),還能促進(jìn)各個(gè)模塊配置的一致性。
5.1 聚合
Maven聚合也稱多模塊,能夠一次構(gòu)建多個(gè)模塊。聚合模塊本身是一個(gè)Maven項(xiàng)目,所以也有自己的POM文件,該POM文件的packaging為pom,并且含有<modules>和<module>元素,如:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wangdh</groupId>
<artifactId>springboot.demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>springboot-mybatis</module>
<module>springboot-web</module>
<module>springboot-quickstart</module>
</modules>
</project>
這里每個(gè)module的值都是一個(gè)當(dāng)前POM的相對(duì)目錄,一般而言,為了方便快速定位內(nèi)容,模塊所處的目錄名稱應(yīng)該與其artifactId一致,不過這不是Maven的要求。
因此,聚合模塊與其他模塊的目錄結(jié)構(gòu)并非一定要父子關(guān)系,通過修改module的值,也能更改為平級(jí)關(guān)系:
<module>../springboot-quickstart</module>
Maven首先會(huì)解析聚合模塊的POM,分析要構(gòu)建的模塊,并計(jì)算出一個(gè)反應(yīng)堆構(gòu)建順序,然后根據(jù)這個(gè)順序依次構(gòu)建各個(gè)模塊。反應(yīng)堆包含了模塊之間繼承和依賴的關(guān)系。模塊間的依賴關(guān)系會(huì)將反應(yīng)堆構(gòu)成一個(gè)有向非循環(huán)圖。
5.2 繼承
繼承解決的是對(duì)重復(fù)依賴和插件配置的抽取。通過定義一個(gè)父模塊,將其他模塊相同的配置抽離到父模塊中,然后繼承父模塊,并且父模塊也是一個(gè)Maven項(xiàng)目,其POM文件的packaging為pom。
子模塊需要增加<parent>元素配置:
<parent>
<artifactId>springboot.demo</artifactId>
<groupId>com.wangdh</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
relativePath定義了父模塊POM文件的位置。默認(rèn)值為../pom.xml,Maven默認(rèn)父POM在上一層目錄下。
POM文件可被繼承的元素有:
groupId:項(xiàng)目組ID,項(xiàng)目坐標(biāo)的核心元素
version:項(xiàng)目版本,項(xiàng)目坐標(biāo)的核心元素
description:項(xiàng)目的描述信息
organization:項(xiàng)目所在組織機(jī)構(gòu)信息
inceptionYear:項(xiàng)目的創(chuàng)始年份
url:項(xiàng)目的URL地址
developers:項(xiàng)目的開發(fā)者信息
contributors:項(xiàng)目的貢獻(xiàn)者信息
distributionManagement:項(xiàng)目的部署配置
issueManagement:項(xiàng)目的缺陷跟著系統(tǒng)信息
ciManagement:項(xiàng)目的持續(xù)集成系統(tǒng)信息
scm:項(xiàng)目的版本控制系統(tǒng)信息
mailingLists:項(xiàng)目的郵件列表信息
properties:自定義的Maven屬性
dependencies:項(xiàng)目的依賴配置
dependencyManagement:項(xiàng)目的依賴管理配置
repositories:項(xiàng)目的倉庫配置
build:項(xiàng)目的源碼目錄配置、輸出目錄配置、插件配置、插件配置管理等
reporting:項(xiàng)目的報(bào)告輸出目錄配置、報(bào)告插件配置等
5.3 聚合與繼承比較


對(duì)于Maven聚合,聚合模塊知道他聚合了哪些模塊,但是被聚合模塊不知道它自己被誰聚合了;
對(duì)于Maven繼承,子模塊知道自己的父模塊是誰,但父模塊不知道自己有多少子模塊。
在實(shí)際使用過程中聚合模塊和父模塊是同一個(gè)模塊。
5.4 依賴管理
子模塊繼承父模塊時(shí),也會(huì)繼承父模塊的依賴配置,假設(shè)添加一個(gè)util的子模塊,該模塊只提供一些簡(jiǎn)單的幫助工具,與springframework完全無關(guān),難道也讓它依賴spring-core、spring-beans、spring-context么?這顯然是不合理的。
Maven提供的dependencyManagement元素既能讓子模塊繼承父模塊的依賴配置,又能保證子模塊依賴使用的靈活性。在dependencyManagement元素下聲明的依賴不會(huì)引入實(shí)際的依賴,不過它能夠約束dependencies下的依賴使用。
在父POM使用dependencyManagement聲明的依賴能夠統(tǒng)一項(xiàng)目范圍中依賴的版本,在子模塊使用依賴的時(shí)候就不需要版本了,只需要簡(jiǎn)單的配置groupId和artifactId就能獲得對(duì)應(yīng)的依賴信息,從而引進(jìn)正確的依賴。
如果子模塊不聲明依賴的使用,即使該依賴已經(jīng)在父POM的dependencyManagement中聲明了,也不會(huì)產(chǎn)生實(shí)際的效果。
如,在父POM定義如下dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
在子模塊使用時(shí),只需要:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
對(duì)于子模塊而言,可以按需添加依賴,對(duì)于整個(gè)項(xiàng)目而言,可以規(guī)范對(duì)依賴的版本號(hào)管理。