五、聚合與繼承

好久沒(méi)有更新了,在這里給大家說(shuō)聲抱歉,實(shí)在是因?yàn)樽罱影嗝Τ晒?,還有一個(gè)原因是我想把《maven實(shí)戰(zhàn)》這本書(shū)剩下的最后幾個(gè)章節(jié)看完在統(tǒng)一做筆記,所以......,好了閑話(huà)少許,現(xiàn)在開(kāi)始我們今天的聚合與繼承章節(jié)的知識(shí)要點(diǎn)回顧

study.jpg

maven的聚合特性能夠把項(xiàng)目的各個(gè)模塊都聚合在一起構(gòu)建,而maven的繼承特性則能夠幫助抽取各個(gè)模塊相同的依賴(lài)和插件等配置,從而讓項(xiàng)目像OPPO那樣從這一刻更清晰

聚合

聚合的目的是為了實(shí)現(xiàn)多個(gè)模塊同時(shí)構(gòu)建,為了配置聚合,我們需要?jiǎng)?chuàng)建獨(dú)立的模塊,為模塊編寫(xiě)pom.xml作為聚合模塊

<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.zheng</groupId>
  <artifactId>account-parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>parent project name</name>
  <modules>
    <module>module1-artifactId</module>
        <module>module2-artifactId</module>
  </modules>
</project>

該項(xiàng)目只需要提供上面的pom.xml配置文件即可,其他src也不需要,這里的packaging必須為pom,否則無(wú)法構(gòu)建
為了方便構(gòu)建,通常將聚合模塊作為項(xiàng)目目錄的最頂層,其他被聚合的子模塊作為項(xiàng)目目錄的子目錄存在
maven在編譯時(shí)會(huì)根據(jù)pom.xml中配置的modules得出一個(gè)反應(yīng)堆構(gòu)建順序,并按照這個(gè)順序編譯項(xiàng)目模塊
建議我們?cè)趧?chuàng)建項(xiàng)目的時(shí)候?yàn)轫?xiàng)目模塊提供一個(gè)合理的name,因?yàn)闃?gòu)建的結(jié)果中是通過(guò)各個(gè)模塊中配置的name來(lái)標(biāo)識(shí)每一個(gè)項(xiàng)目模塊的構(gòu)件狀態(tài)的
如下所示,是對(duì)一個(gè)account-parent項(xiàng)目的構(gòu)件結(jié)果:

image.png

繼承

繼承目的是為了將一些公共的配置抽取出來(lái),方便其他模塊共用,為了實(shí)現(xiàn)模塊繼承,需要以下幾步:

  1. 創(chuàng)建一個(gè)新的項(xiàng)目模塊,并配置其pom.xml
<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.zheng</groupId>
  <artifactId>account-parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>parent project name</name>
</project>

跟聚合一樣,父模塊中的packaging也必須要求是pom

  1. 編寫(xiě)其他子模塊引用父模塊
<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>
<parent>
    <groupId>com.zheng</groupId>
    <artifactId>account-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../account-parent/pom.xml</relativePath>
  </parent>
  <groupId>com.zheng</groupId>
  <artifactId>account-parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>parent project name</name>
</project>

上面通過(guò)parent加入父模塊在maven倉(cāng)庫(kù)中的坐標(biāo)來(lái)引用maven
通過(guò)relativePath相對(duì)路徑的方式指定了父模塊基于當(dāng)前子模塊的位置,maven在構(gòu)建子模塊的時(shí)候就不會(huì)要求父模塊一定要先于安裝到本地倉(cāng)庫(kù),因?yàn)橥ㄟ^(guò)該標(biāo)簽指定的相對(duì)路徑已經(jīng)可以明確指定到父模塊,當(dāng)然如果本地倉(cāng)庫(kù)和relativePath所提供的路徑找不到父模塊,那么構(gòu)建將會(huì)失敗

可繼承的pom元素

groupId: 項(xiàng)目組id,項(xiàng)目坐標(biāo)核心元素
version: 項(xiàng)目版本,項(xiàng)目坐標(biāo)核心元素
description: 項(xiàng)目描述信息
organization: 項(xiàng)目組織信息
inceptionYear: 創(chuàng)始年份
url: 項(xiàng)目地址,這里可以向項(xiàng)目的index連接
developers: 項(xiàng)目開(kāi)發(fā)者信息
contributors: 項(xiàng)目貢獻(xiàn)者信息
distributionManagement: 項(xiàng)目的部署地址
issueManagement: 項(xiàng)目缺陷跟蹤信息
ciManagement: 項(xiàng)目持續(xù)集成的部署信息
scm: 項(xiàng)目的版本控制系統(tǒng)信息
mailingLists: 項(xiàng)目的郵件地址列表信息
properties: 自定義的maven屬性
dependencies: 項(xiàng)目依賴(lài)
dependencyMangement: 項(xiàng)目依賴(lài)管理配置
repositories: 項(xiàng)目倉(cāng)庫(kù)
build: 項(xiàng)目源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等
reporting: 項(xiàng)目的輸出目錄配置、報(bào)告插件配置等
通過(guò)build參數(shù)可以看到插件配置也可以被繼承

依賴(lài)管理

dependenciesdependencyManagement
在父模塊pom.xml中的dependencies中引入的依賴(lài)會(huì)被所有引用該父模塊的子模塊繼承,但并不是所有的子模塊都會(huì)用到父模塊中聲明的依賴(lài),所以為了防止多余的依賴(lài),父容器中可以通過(guò)dependencyManagement來(lái)聲明jar包依賴(lài)。
dependencyManagement中聲明的依賴(lài)配置會(huì)被子模塊繼承,但是不會(huì)被實(shí)際使用,除非子模塊顯示通過(guò)groupId:artifactId聲明需要引用該依賴(lài)
使用dependencyManagement的好處是可以在父模塊中對(duì)jar包版本進(jìn)行統(tǒng)一管理,推薦這么做

import依賴(lài)范圍

在前面依賴(lài)范圍提到過(guò)import,它的作用只會(huì)對(duì)pom.xml中配置的dependencyManagement有效
import的作用是:將目標(biāo)pom中的dependencyManagement配置導(dǎo)入并合并到當(dāng)前pom.xml
import依賴(lài)范圍是除了使用代碼復(fù)制和繼承之外的又一個(gè)可以將外部配置導(dǎo)入的方式,下面是具體配置:
父項(xiàng)目b

<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.cbm.stu</groupId>
    <artifactId>maven-parent-b</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <name>maven-parent-b</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.1</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.40</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

繼承b的子項(xiàng)目

<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.cbm.stu</groupId>
    <artifactId>maven-study-mail</artifactId>
    <version>2.1</version>
    <packaging>jar</packaging>
    <name>maven-study-mail</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- 此處繼承b 項(xiàng)目,type為pom,scope 為 import -->
            <dependency>
                <groupId>com.cbm.stu</groupId>
                <artifactId>maven-parent-b</artifactId>
                <version>1.0.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- 從繼承的父項(xiàng)目中繼承依賴(lài) -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

import依賴(lài)范圍由于其特殊性,它的類(lèi)型(type)一般都是pom,scopeimport

插件管理

與依賴(lài)管理相似的是插件管理,maven中提供了plugins, pluginManagement兩個(gè)元素,這兩個(gè)元素的用途與依賴(lài)管理中的dependenciesdependencyManagement用法一致
這里不做贅述

聚合與繼承之間的關(guān)系

不同點(diǎn):

  1. 聚合與繼承是兩個(gè)概念,其目的是完全不同的,聚合是為了解決多模塊同時(shí)構(gòu)建的問(wèn)題,而繼承則是為了解決多模塊重復(fù)配置問(wèn)題
  2. 對(duì)于聚合模塊來(lái)說(shuō),它知道有哪些子模塊需要被聚合,(<modules>),而對(duì)于繼承來(lái)說(shuō)它不知道有哪些子模塊繼承了它,但相反,子模塊知道他們繼承的是哪一個(gè)父模塊(<parent>)
    聚合模塊.png

    繼承模塊.png

    相同點(diǎn):
    聚合與繼承模塊pom的類(lèi)型(type)都是pom,他們都除了包含一個(gè)pom.xml文件之外,沒(méi)有其他東西
    推薦做法:為了方便,可以將聚合和繼承兩者合成一個(gè)模塊,在一個(gè)父模塊中配置聚合和繼承

約定優(yōu)于配置

使用maven比使用ant配置更少,更方便,雖然用戶(hù)感覺(jué)上自己配置的東西少了,其實(shí)是maven內(nèi)部將某一些配置提前預(yù)設(shè)好了,比如在超級(jí)pom中可以看到的:

  1. 源碼目錄為src/main/java
  2. 編譯輸出目錄為target/classes
  3. 打包方式為jar
  4. 包輸出目錄為target/
    所有項(xiàng)目的pom.xml都繼承與超級(jí)pom中的配置,超級(jí)pom具體位置在:
    ${MVN_HOME}/lib/maven-model-builder-x.x.x.jar/org/apache/maven/model/pom-4.0.0.xml

反應(yīng)堆

對(duì)于單模塊,反應(yīng)堆就是它本身,但對(duì)于多個(gè)模塊項(xiàng)目來(lái)說(shuō),反應(yīng)堆就包含了模塊之間繼承與依賴(lài)的關(guān)系
maven的實(shí)際構(gòu)建順序是這樣形成的:

  1. maven按序讀取pom,如果該pom沒(méi)有依賴(lài)模塊,則直接進(jìn)行構(gòu)建
  2. 如果依賴(lài)了其他模塊,那么先構(gòu)建其他模塊
  3. 遞歸1,2直到完成整個(gè)項(xiàng)目的構(gòu)建工作
    特別說(shuō)明,項(xiàng)目模塊之間的依賴(lài)配置,不能出現(xiàn)循環(huán)依賴(lài)的現(xiàn)象,也就是A依賴(lài)B,B也依賴(lài)于A,這樣的配置將會(huì)導(dǎo)致maven構(gòu)建失敗

裁剪反應(yīng)堆

對(duì)聚合模塊運(yùn)行maven命令比如mvn clean install,maven會(huì)根據(jù)計(jì)算出來(lái)的反應(yīng)堆順序?qū)⑷孔幽K都構(gòu)建完畢并安裝到本地倉(cāng)庫(kù),為了選擇性的構(gòu)件某些模塊進(jìn)行構(gòu)建而不是將所有模塊進(jìn)行構(gòu)建,那么可以采用maven提供的幾條裁剪反應(yīng)堆命令:
-am also make 構(gòu)建模塊同時(shí)構(gòu)建所列模塊依賴(lài)的其他模塊
-amd also make dependency構(gòu)建模塊同時(shí)構(gòu)建依賴(lài)當(dāng)前模塊的其他模塊
-pl --projects 構(gòu)建指定的模塊,多個(gè)模塊用,分隔
-rf resume-from 在計(jì)算出的反應(yīng)堆順序基礎(chǔ)上,從指定模塊開(kāi)始向后構(gòu)建
下面是各個(gè)命令的實(shí)例:
假設(shè)存在account-parent,account-email,account-persist三個(gè)模塊,他們之間的關(guān)系如下:

模塊間依賴(lài)關(guān)系.png

-pl:構(gòu)建指定模塊
mvn clean install -pl account-parent
將會(huì)構(gòu)建account-parent模塊

-am:構(gòu)建模塊并構(gòu)建其依賴(lài)的其他模塊
mvn clean install -pl account-email -am
將會(huì)構(gòu)建account-parent/account-email模塊

-amd: 構(gòu)建模塊并構(gòu)建依賴(lài)它的其他模塊
mvn clean install -pl account-parent -amd
將會(huì)構(gòu)建account-parent/account-email/account-persist

-rf 指定構(gòu)建的起始模塊,假設(shè)模塊依賴(lài)關(guān)系如下
account-parent
- account-email
- account-persist
mvn clean install -pl account-parent -amd -rf account-persist
將會(huì)構(gòu)建account-parent/account-persist,而跳過(guò)account-email模塊的構(gòu)建
好了,以上就是本章的重點(diǎn)知識(shí),鍵盤(pán)敲到這里,再看看現(xiàn)在的時(shí)間0:39,再想到明天臺(tái)風(fēng)天還要上班,趕緊洗干凈滾床上睡覺(jué)啦?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、聚合 想要一次構(gòu)建兩個(gè)項(xiàng)目,而不是到兩個(gè)模塊目錄下分別執(zhí)行mvn命令。 為了能使用一條命令構(gòu)建兩個(gè)模塊,需要?jiǎng)?chuàng)...
    JarvisTH閱讀 680評(píng)論 0 0
  • 何為Maven的聚合 假設(shè)有這么一個(gè)場(chǎng)景,有ABC三個(gè)項(xiàng)目,需要一次構(gòu)建三個(gè)項(xiàng)目,而不是分別到每個(gè)項(xiàng)目下面執(zhí)行mv...
    超級(jí)大雞腿閱讀 602評(píng)論 0 0
  • Maven的聚合特性能夠把項(xiàng)目的各個(gè)模塊聚合在一起構(gòu)建,而繼承特性則能夠幫助抽取各模塊相同的依賴(lài)和插件等配置,在簡(jiǎn)...
    洛楊凡閱讀 713評(píng)論 0 0
  • 那樣淡然微笑的女子,一直是心里的慰籍和向往。 此心安處是吾鄉(xiāng)。 面對(duì)迎面而來(lái)的氣運(yùn)加諸于身的苦楚反復(fù),苦難侮辱,以...
    銘玥詠全閱讀 256評(píng)論 0 2
  • 雨不大不小 剛剛好 不纏綿也不討人厭煩 兩條鐵軌正是我生活軌跡 一頭連著工作 一頭連著家 旅途行人不多不少 剛剛滿(mǎn)...
    躁動(dòng)的青春閱讀 258評(píng)論 0 1

友情鏈接更多精彩內(nèi)容