何為Maven的聚合
假設(shè)有這么一個(gè)場景,有ABC三個(gè)項(xiàng)目,需要一次構(gòu)建三個(gè)項(xiàng)目,而不是分別到每個(gè)項(xiàng)目下面執(zhí)行mvn命令,這個(gè)時(shí)候Maven的聚合特性就是為了該需求而服務(wù)的。為了解決這個(gè)問題,現(xiàn)需要?jiǎng)?chuàng)建一個(gè)父項(xiàng)目,注意:作為一個(gè)聚合項(xiàng)目,打包方式packaging為pom,下面就是聚合項(xiàng)目的例子
<?xml version="1.0" encoding="UTF-8"?>
<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.fbb</groupId>
? <artifactId>fbbParent</artifactId>
? <version>1.0</version>
? <packaging>pom</packaging>
? <modules>
? ? <module>fbb-A</module>
? ? <module>fbb-B</module>
? ? <module>fbb-C</module>
? </modules>
? <dependencies>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>log4j</groupId>
? ? ? ? ? ? <artifactId>log4j</artifactId>
? ? ? ? ? ? <version>1.2.17</version>
? ? ? ? </dependency>
? </dependencies>
</project>
當(dāng)在父項(xiàng)目下面執(zhí)行mvn命令 mvn clean install 的時(shí)候,Maven會(huì)先解析結(jié)合項(xiàng)目的pom,分析要構(gòu)建的項(xiàng)目,并且計(jì)算出一個(gè)反應(yīng)堆構(gòu)建順序,然后根據(jù)這個(gè)順序進(jìn)行構(gòu)建。
何為Maven繼承
以上面的例子來說,可以做到了啟動(dòng)聚合項(xiàng)目,其下的項(xiàng)目都能一起執(zhí)行,但是單單是構(gòu)建,確實(shí)沒什么問題,但是三個(gè)項(xiàng)目,中存在相同的依賴,也很正常,通常來說,一段代碼重復(fù)出現(xiàn)兩次以上,就得考慮著需要優(yōu)化了,Maven中的繼承能夠解決這個(gè)需求,通過創(chuàng)建一個(gè)父項(xiàng)目,配置一些公共的配置,讓子類繼承,做到一處聲明,多個(gè)地方使用的效果,同樣的作為父項(xiàng)目,它的打包方式跟聚合項(xiàng)目一樣,packaging也為pom
子類A的配置
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
? <modelVersion>4.0.0</modelVersion>
? <parent>
? ? <groupId>com.fbb</groupId>
? ? <artifactId>fbbParent</artifactId>
? ? <version>1.0</version>
? </parent>
? <artifactId>fbb-admin</artifactId>
? <packaging>war</packaging>
? <name>fbb-admin Maven Webapp</name>
? <url>http://maven.apache.org</url>
</project>
子項(xiàng)目B與子項(xiàng)目C大同小異,就不做舉例子了,上面可以看出聲明了一個(gè)Parent的標(biāo)簽,通過groupId,artifactId,version,定位到父項(xiàng)目,可以看出子項(xiàng)目定義的時(shí)候,groupId,artifactId都沒有定義,這不意味著沒有,是因?yàn)槔^承了父項(xiàng)目的groupId,artifactId,所以不需要聲明,當(dāng)然如果子項(xiàng)目的groupId,artifactId,需要不一樣,可以顯示的聲明在pom上。
可以被繼承的Pom元素
groupId:項(xiàng)目組ID,項(xiàng)目坐標(biāo)的核心元素
version:項(xiàng)目版本,項(xiàng)目坐標(biāo)的核心因素
description:項(xiàng)目的描述信息
organization:項(xiàng)目的組織信息
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)
malilingLists:項(xiàng)目的郵件列表信息
properties:自定義的Maven屬性
dependencies:項(xiàng)目的依賴配置
dependencyManagement:項(xiàng)目的依賴管理配置
repositories:項(xiàng)目的倉庫配置
build:包括項(xiàng)目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等
reporting:包括項(xiàng)目的報(bào)告輸出目錄配置、報(bào)告插件配置等
繼承的一些靈活措施
如上面的例子,當(dāng)三個(gè)子項(xiàng)目繼承父項(xiàng)目的時(shí)候,相應(yīng)的依賴,都會(huì)繼承,但是,實(shí)際情況上,不可能每個(gè)項(xiàng)目都是完完全玩一樣的一套依賴,比如說我有一個(gè)子項(xiàng)目,僅僅是用來提供一些工具,這個(gè)時(shí)候spring,mybatis相關(guān)的依賴,它們就不應(yīng)該出現(xiàn)在子項(xiàng)目里面,如果出現(xiàn),這就顯得不合理了。Maven提供的dependencyManagement元素既能夠讓子模塊繼承父模塊的依賴配置,又能保證子模塊依賴使用的靈活性,它的聲明不會(huì)引入實(shí)際的依賴。
<?xml version="1.0" encoding="UTF-8"?>
<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.fbb</groupId>
? <artifactId>fbbParent</artifactId>
? <version>1.0</version>
? <packaging>pom</packaging>
? <modules>
? ? <module>fbb-A</module>
? ? <module>fbb-B</module>
? ? <module>fbb-C</module>
? </modules>
? <properties>
? ? ? <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
? ? ? <junit.version>4.9</junit.version>
</properties>
<dependencyManagement>
? ? <dependencies>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>junit</groupId>
? ? ? ? ? ? <artifactId>junit</artifactId>
? ? ? ? ? ? <version>${junit.version}</version>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>? ?
? ? </dependencies>
</dependencyManagement>
</project>
子類A的配置
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
? <modelVersion>4.0.0</modelVersion>
? <parent>
? ? <groupId>com.fbb</groupId>
? ? <artifactId>fbbParent</artifactId>
? ? <version>1.0</version>
? </parent>
? <artifactId>fbb-admin</artifactId>
? <packaging>war</packaging>
? <name>fbb-admin Maven Webapp</name>
? <url>http://maven.apache.org</url>
<dependencies>
? ? <dependency>
? ? ? ? <groupId>junit</groupId>
? ? ? ? <artifactId>junit</artifactId>
? ? </dependency>? ?
</dependencies>
</project>
可以發(fā)現(xiàn)在子類聲明依賴的時(shí)候,版本跟scope都沒有聲明了,因?yàn)闀?huì)使用在父類中配置,但是其實(shí)可以發(fā)現(xiàn),配置相比不繼承的,沒有節(jié)省多少內(nèi)容,但是這種方式可以讓各個(gè)項(xiàng)目的版本統(tǒng)一,項(xiàng)目的依賴更加的靈活。
插件的依賴管理
插件跟項(xiàng)目依賴一樣,有類似于dependencyManagement的元素pluginManagement元素能進(jìn)行類似的需求,在該元素下配置的依賴,不會(huì)造成實(shí)際的插件調(diào)用行為,當(dāng)pom配置了plugin元素,而且groupId,artifactId匹配的時(shí)候,pluginManagement就會(huì)起到真正的作用。
聚合繼承的反應(yīng)堆順序
構(gòu)建順序的形成過程:Maven按序讀取Pom,如果該P(yáng)om沒有依賴模塊,那么就構(gòu)建該模塊,如果有就先構(gòu)建其依賴模塊,如果其依賴模塊還有其他的依賴模塊,就先構(gòu)建它的依賴模塊,總之就是先一步的構(gòu)件其依賴的模塊,模塊間的依賴關(guān)系使得反應(yīng)堆順序形成一個(gè)有向非循環(huán)圖,這個(gè)圖不允許出現(xiàn)循環(huán),循環(huán)依賴,Maven就會(huì)報(bào)錯(cuò)。