Maven實(shí)戰(zhàn)之聚合與繼承

何為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ò)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容