Maven系列第7篇:聚合、繼承、單繼承問題詳解,必備技能!
- 2019 年 11 月 25 日
- 筆記
maven系列目標:從入門開始開始掌握一個高級開發所需要的maven技能。
這是maven系列第7篇。
整個maven系列的內容前後是有依賴的,如果之前沒有接觸過maven,建議從第一篇看起,本文尾部有maven完整系列的連接。
本篇內容
- maven中聚合詳解
- maven中繼承詳解
- pom.xml中parent元素的使用詳解
- pom.xml中dependencyManagement元素使用詳解
- pom.xml中pluginManagement元素使用詳解
- 單繼承存在的問題及解決方案詳解(springboot,springcloud中會常用)
- 解答上一篇遺留的2個問題
聚合
原始需求
我們需要使用java做一個電商網站,涉及到:pc端網站、h5微站、移動端接口部分,那麼我們可以使用maven創建3個項目用於這3塊業務的開發,3個項目名稱如下:
javacode2018-pc javacode2018-h5 javacode2018-api
這3個項目的groupId都是com.javacode2018
,artifactId取上面的,我們使用maven來搭建項目結構。
實現
創建第一個javacode2018-pc項目
打開idea,點擊File->New->Project
,選擇Maven
,如下:

點擊Next
,輸入項目坐標信息,如下:

點擊Next
,輸入Project name 為javacode2018-pc
,如下:

點擊Finish
,創建成功,如下:

配置一下idea的maven環境,點擊File->Settings
,如下圖:

點擊上面的OK
完成配置。
大家再按照上面一樣的操作,分別創建另外2個項目javacode2018-h5
和javacode2018-api
,創建完成之後,另外2個項目如下圖:


上面3個項目由整個項目組6個人共同開發,這幾個項目經常一起上線,上線過程,先由開發進行打包,然後將幾個包發給運行進行發佈。我們使用mvn package
進行打包,需要在每個項目的pom.xml
所在目錄都去執行一次這個命令,也就是說需要執行3次,這個電商項目還會涉及到後台系統、bi系統、監控系統等等,可能最後會多達10個小項目,那時候我們每次上線都需要執行10次打包操作,這個過程是相當繁瑣的。
那麼maven有沒有更好的辦法來解決這個事情呢?
這個用到的就是我們本次要說的maven中的聚合
。
整個電商我們可以作為一個大的系統,上面的pc端、h5微站、api接口、後台系統、bi系統、監控系統都可以作為裏面的一個具體比較大一個模塊。
我們使用maven聚合
功能來實現上面的需求,我們需要創建一個額外的maven項目javacode-aggregator
來管理上面3個項目,然後只用在javacode-aggregator
項目中執行mvn
命令,就會自動為其他3個項目自動執行同樣的mvn
命令。
Maven聚合
maven聚合需要創建一個新的maven項目, 用來管理其他的maven構件模塊,新的maven項目中加入如下配置:
<modules> <module>模塊1</module> <module>模塊2</module> <module>模塊n</module> </modules> <package>pom</package>
新的項目中執行任何
mvn
命令,都會modules
中包含的所有模塊執行同樣的命令,而被包含的模塊不需要做任何特殊的配置,正常的maven項目就行。 注意上面的module
元素,這部分是被聚合的模塊pom.xml
所在目錄的相對路徑。 package的值必須為pom,這個需要注意。 下面看案例。
實操案例
下面過程仔細看了。
創建項目`javacode-aggregator`
打開idea,點擊File->New->Project
,選擇Maven
,如下:

點擊Next
,輸入項目坐標信息,如下:

點擊Next
,輸入Project name 為javacode-aggregator
,如下:

點擊Finish
,創建成功,如下:

配置一下idea的maven環境,點擊File->Settings
,如下圖:

刪除下面無用的代碼:

項目變成了下面這樣:

pom.xml
中加入下面配置:
<packaging>pom</packaging>
最後pom.xml內容如下:
<?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.javacode2018</groupId> <artifactId>javacode-aggregator</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> </project>
創建`javacode2018-pc` 模塊
注意這裡說的是模塊,不再是創建項目,過程仔細看。
idea中選中javacode-aggregator

點擊File->New->Module
,準備創建模塊,如下圖:

選擇Maven
,如圖:

點擊Next
,如下:

點擊下面的...
按鈕,選擇None
,如下:



輸入坐標信息,如下:

點擊Next
,輸入Module name :javacode2018-pc
,如下:

點擊Finish
,完成javacode-2018
模塊的創建,如下:

我們來看一下javacode-aggregator
的pom.xml,多了一部分,如下:

注意上面的
<packaging>pom</packaging>
創建javacode2018-h5模塊
創建步驟和上面javacode2018-pc
步驟一樣。
創建javacode2018-api模塊
創建步驟和上面javacode2018-pc
步驟一樣。
我們看一下項目最終結構,如下圖:

看一下上圖中的javacode-aggregator
項目的pom.xml
,modules
元素中多出了3部分。
再來看看其他3個模塊的pom文件,和普通的pom.xml一樣,如下圖:



在javacode-aggregator/pom.xml
目錄中執行mvn package
感受一下效果:
D:codeIdeaProjectsjavacode-aggregator>mvn package [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] javacode2018-pc [jar] [INFO] javacode2018-h5 [jar] [INFO] javacode2018-api [jar] [INFO] javacode-aggregator [pom] [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------ [INFO] Building javacode2018-pc 1.0-SNAPSHOT [1/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode-aggregatorjavacode2018-pcsrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-pc --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-pc --- [INFO] Building jar: D:codeIdeaProjectsjavacode-aggregatorjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] [INFO] ------------------< com.javacode2018:javacode2018-h5 >------------------ [INFO] Building javacode2018-h5 1.0-SNAPSHOT [2/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-h5 --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-h5 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-h5 --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode-aggregatorjavacode2018-h5srctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-h5 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-h5 --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-h5 --- [INFO] Building jar: D:codeIdeaProjectsjavacode-aggregatorjavacode2018-h5targetjavacode2018-h5-1.0-SNAPSHOT.jar [INFO] [INFO] -----------------< com.javacode2018:javacode2018-api >------------------ [INFO] Building javacode2018-api 1.0-SNAPSHOT [3/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-api --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-api --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-api --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode-aggregatorjavacode2018-apisrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-api --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-api --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-api --- [INFO] Building jar: D:codeIdeaProjectsjavacode-aggregatorjavacode2018-apitargetjavacode2018-api-1.0-SNAPSHOT.jar [INFO] [INFO] ----------------< com.javacode2018:javacode-aggregator >---------------- [INFO] Building javacode-aggregator 1.0-SNAPSHOT [4/4] [INFO] --------------------------------[ pom ]--------------------------------- [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for javacode-aggregator 1.0-SNAPSHOT: [INFO] [INFO] javacode2018-pc .................................... SUCCESS [ 2.542 s] [INFO] javacode2018-h5 .................................... SUCCESS [ 0.195 s] [INFO] javacode2018-api ................................... SUCCESS [ 0.218 s] [INFO] javacode-aggregator ................................ SUCCESS [ 0.024 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.223 s [INFO] Finished at: 2019-11-19T13:28:00+08:00 [INFO] ------------------------------------------------------------------------
我們分析一下上面的輸出:
[INFO] Reactor Build Order: [INFO] [INFO] javacode2018-pc [jar] [INFO] javacode2018-h5 [jar] [INFO] javacode2018-api [jar] [INFO] javacode-aggregator [pom]
上面這個列出了需要構件的maven構件列表及順序,共有4個構件,3個jar包,1個pom類型的構件。
然後開始按照上面列出的順序,一個個開始執行mvn package
命令,最後4個都執行成功了,我們來看一下最終產生的效果,如下圖:

從上圖中我們可以看到3個模塊都生成了jar包,說明我們執行了一次mvn package
,分別在3個模塊中都運行了,我們在來執行一下mvn clean
清理代碼,感受一下最終效果:
D:codeIdeaProjectsjavacode-aggregator>mvn clean [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] javacode2018-pc [jar] [INFO] javacode2018-h5 [jar] [INFO] javacode2018-api [jar] [INFO] javacode-aggregator [pom] [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------ [INFO] Building javacode2018-pc 1.0-SNAPSHOT [1/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javacode2018-pc --- [INFO] Deleting D:codeIdeaProjectsjavacode-aggregatorjavacode2018-pctarget [INFO] [INFO] ------------------< com.javacode2018:javacode2018-h5 >------------------ [INFO] Building javacode2018-h5 1.0-SNAPSHOT [2/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javacode2018-h5 --- [INFO] Deleting D:codeIdeaProjectsjavacode-aggregatorjavacode2018-h5target [INFO] [INFO] -----------------< com.javacode2018:javacode2018-api >------------------ [INFO] Building javacode2018-api 1.0-SNAPSHOT [3/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javacode2018-api --- [INFO] Deleting D:codeIdeaProjectsjavacode-aggregatorjavacode2018-apitarget [INFO] [INFO] ----------------< com.javacode2018:javacode-aggregator >---------------- [INFO] Building javacode-aggregator 1.0-SNAPSHOT [4/4] [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javacode-aggregator --- [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for javacode-aggregator 1.0-SNAPSHOT: [INFO] [INFO] javacode2018-pc .................................... SUCCESS [ 0.250 s] [INFO] javacode2018-h5 .................................... SUCCESS [ 0.067 s] [INFO] javacode2018-api ................................... SUCCESS [ 0.068 s] [INFO] javacode-aggregator ................................ SUCCESS [ 0.034 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.605 s [INFO] Finished at: 2019-11-19T13:34:42+08:00 [INFO] ------------------------------------------------------------------------
項目結構如下圖:

3個項目中的target都被清理掉了,是不是感覺很爽。
上面介紹了pom.xml中的module
元素的值為被聚合的模塊pom.xml所在的目錄路徑,可以是相對路徑,也可以是絕對路徑,上面演示的是相對路徑,大家可以自己去玩一下絕對路徑的情況。
聚合的功能中,聚合模塊的pom.xml中通過modules->module
來引用被聚合的模塊,被聚合的模塊是不用感知自己被聚合了,所以被聚合的模塊中pom.xml
中是不知道javacode-aggregator
的存在的。
繼承
需求
細心的朋友已經發現了javacode2018-pc、javacode2018-h5、javacode2018-api
3個項目的groupId、version
都是一樣的。還有這幾個項目準備都是用springmvc、mybatis開發的,所以需要引入依賴如下:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.1.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.3</version> </dependency>
3個項目中出現了同樣的配置,一個配置出現了多份,作為開發者,我想你們和我一樣,是無法接受的,必須要尋求一些方法來解決,需要將公共的部分提取出來共用。
maven也為我們考慮到了這種情況,maven中使用繼承來解決這個問題。
繼承的實現
操作分為3步驟:
- 創建一個父maven構件,將依賴信息放在pom.xml中 <dependencies> <dependency>依賴的構件的坐標信息</dependency> <dependency>依賴的構件的坐標信息</dependency> <dependency>依賴的構件的坐標信息</dependency> </dependencies>
- 將父構件的package元素的值置為pom <packaging>pom</packaging>
- 在子構件的pom.xml引入父構件的配置: <parent> <groupId>父構件groupId</groupId> <artifactId>父構件artifactId</artifactId> <version>父構件的版本號</version> <relativePath>父構件pom.xml路徑</relativePath> </parent>
relativePath表示父構件pom.xml相對路徑,默認是
../pom.xml
,所以一般情況下父子結構的maven構件在目錄結構上一般也採用父子關係。
實操案例
先創建一個父項目javacode-parent
,坐標信息如下:
<groupId>com.javacode2018</groupId> <artifactId>javacode2018-parent</artifactId> <version>1.0-SNAPSHOT</version>
創建過程大家已經輕車熟路了,就不演示了,最終如下圖:

刪除無用的2目錄.idea和src

創建子模塊`javacode2018-pc` 模塊
注意這裡說的是模塊了,不在是創建項目了,過程仔細看。
idea中選中javacode-parent
,如下圖:

點擊File->New->Module
,準備創建模塊,如下圖:

選中Maven
,如下圖:

點擊Next
,這個頁面需要注意了,默認如下圖:

此時我們點擊第一個...
按鈕,這個按鈕是設置聚合的,所以選中None
,如下圖:


變成了下面這樣:

輸入構件信息,如下圖:

點擊Next
,輸入Module-name
的值為javacode2018-pc
,如下圖:

點擊Finish
完成創建操作,如下圖:

上圖中,看一下javacode2018-pc
的pom.xml,多了個parent
元素,並且這個pom.xml中構件的groupId、version
都沒有了,這個pom.xml
繼承了javacode2018-parent/pom.xml
中的內容,他們的groupId、version
都是一樣的,子構件可以從父pom.xml中繼承這些內容,所以如果是一樣的情況,可以不寫。
創建另外兩個子模塊javacode2018-h5、javacode2018-api
步驟參考javacode2018-pc
模塊的創建過程。
最終項目如下圖:

下面我們來看一下4個pom.xml的內容。
javacode2018-parent/pom.xml的內容:
<?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.javacode2018</groupId> <artifactId>javacode2018-parent</artifactId> <version>1.0-SNAPSHOT</version> </project>
javacode2018-pc/pom.xml的內容:
<?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"> <parent> <artifactId>javacode2018-parent</artifactId> <groupId>com.javacode2018</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>javacode2018-pc</artifactId> </project>
javacode2018-h5/pom.xml的內容:
<?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"> <parent> <artifactId>javacode2018-parent</artifactId> <groupId>com.javacode2018</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>javacode2018-h5</artifactId> </project>
javacode2018-api/pom.xml的內容:
<?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"> <parent> <artifactId>javacode2018-parent</artifactId> <groupId>com.javacode2018</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>javacode2018-api</artifactId> </project>
我們在父構件javacode2018-parent/pom.xml中加入下面配置:
<packaging>pom</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.1.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.3</version> </dependency> </dependencies>
使用下面命令在javacode2018-parent/pom.xml所在目錄看一下javacode2018-parent構件依賴情況:
D:codeIdeaProjectsjavacode2018-parent>mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ----------------< com.javacode2018:javacode2018-parent >----------------- [INFO] Building javacode2018-parent 1.0-SNAPSHOT [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ javacode2018-parent --- [INFO] com.javacode2018:javacode2018-parent:pom:1.0-SNAPSHOT [INFO] +- org.springframework:spring-web:jar:5.2.1.RELEASE:compile [INFO] | +- org.springframework:spring-beans:jar:5.2.1.RELEASE:compile [INFO] | - org.springframework:spring-core:jar:5.2.1.RELEASE:compile [INFO] | - org.springframework:spring-jcl:jar:5.2.1.RELEASE:compile [INFO] - org.mybatis:mybatis-spring:jar:2.0.3:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.544 s [INFO] Finished at: 2019-11-19T14:58:21+08:00 [INFO] ------------------------------------------------------------------------
mvn dependency:tree 這個插件可以根據pom.xml的配置,列出構件的依賴樹信息。
我們再來看看javacode2018-pc/pom.xml構件的依賴信息:
D:codeIdeaProjectsjavacode2018-parent>cd javacode2018-pc D:codeIdeaProjectsjavacode2018-parentjavacode2018-pc>mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------- [INFO] Building javacode2018-pc 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ javacode2018-pc --- [INFO] com.javacode2018:javacode2018-pc:jar:1.0-SNAPSHOT [INFO] +- org.springframework:spring-web:jar:5.2.1.RELEASE:compile [INFO] | +- org.springframework:spring-beans:jar:5.2.1.RELEASE:compile [INFO] | - org.springframework:spring-core:jar:5.2.1.RELEASE:compile [INFO] | - org.springframework:spring-jcl:jar:5.2.1.RELEASE:compile [INFO] - org.mybatis:mybatis-spring:jar:2.0.3:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.093 s [INFO] Finished at: 2019-11-19T14:59:34+08:00 [INFO] ------------------------------------------------------------------------
從上圖中可以看到
javacode2018-pc
依賴的jar和父構件javacode2019-parent
的一樣,說明從父類繼承了這些依賴。 其他2個子構件,大家也可以去看一下,依賴關係都從父構件繼承過來了。
relativePath元素
上面演示的父構件和子構件的目錄結構剛好符合父子關係,如果父構件和子構件的目錄不是父子關係,比如都位於同等級別的目錄或者位於更複雜的目錄的時候,此時我們需要在子pom.xml
的parent
元素中使用relativePath
元素來指定父pom.xml
相對路徑位置,這個值我們上面沒有指定,默認是../pom.xml
,表示父pom.xml位於子pom.xml的上一級目錄,我們的模塊剛好符合這種關係,所以這個值省略了。
正確的設置relativePath
是非常重要的,這個需要注意,子模塊中執行mvn
命令的時候,會去找父pom.xml
的配置,會先通過relativePath
指定的路徑去找,如果找不到,會嘗試通過坐標在本地倉庫進行查找,如果本地找不到,會去遠程倉庫找,如果遠程倉庫也沒有,會報錯。
可以通過繼承的元素有以下這些
上面我們看到了groupId、version、dependency中的依賴
在子pom.xml
中都沒有寫,這些都是從父pom.xml
中繼承過來的,還有很多元素也可以被繼承過來,下面我們列個清單:
- groupId:項目組ID,項目坐標的核心元素
- version:項目版本,項目坐標的核心元素
- description:項目的描述信息
- organization:項目的組織信息
- inceptionYear:項目的創始年份
- url:項目的url地址
- developers:項目的開發者信息
- contributors:項目的貢獻者信息
- distributionManagement:項目的部署配置信息
- issueManagement:項目的缺陷跟蹤系統信息
- ciManagement:項目的持續集成系統信息
- scm:項目的版本控制系統信息
- mailingLists:項目的郵件列表信息
- properties:自定義的maven屬性配置信息
- dependencyManagement:項目的依賴管理配置
- repositories:項目的倉庫配置
- build:包括項目的源碼目錄配置、輸出目錄配置、插件管理配置等信息
- reporting:包括項目的報告輸出目錄配置、報告插件配置等信息
依賴管理(dependencyManagement)
大家是否發現了,上面的繼承存在的一個問題,如果我在新增一個子構件,都會默認從父構件中繼承依賴的一批構建,父pom.xml中配置的這些依賴的構建可能是其他項目不需要的,可能某個子項目只是想使用其中一個構件,但是上面的繼承關係卻把所有的依賴都給傳遞到子構件中了,這種顯然是不合適的。
maven中也考慮到了這種情況,可以使用dependencyManagement
元素來解決這個問題。
maven提供的dependencyManagement元素既能讓子模塊繼承到父模塊的依賴配置,又能保證子模塊依賴使用的靈活性,在dependencyManagement元素下聲明的依賴不會引入實際的依賴,他只是聲明了這些依賴,不過它可以對dependencies
中使用的依賴起到一些約束作用。
修改javacode2018-parent/pom.xml
配置如下:
<?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.javacode2018</groupId> <artifactId>javacode2018-parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.1.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.3</version> </dependency> </dependencies> </dependencyManagement> </project>
可以看到我們將dependencies
配置移到dependencyManagement
下面了。
我們使用下面命令看一下項目的依賴情況:
D:codeIdeaProjectsjavacode2018-parent>mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ----------------< com.javacode2018:javacode2018-parent >----------------- [INFO] Building javacode2018-parent 1.0-SNAPSHOT [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ javacode2018-parent --- [INFO] com.javacode2018:javacode2018-parent:pom:1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.756 s [INFO] Finished at: 2019-11-19T15:44:52+08:00 [INFO] ------------------------------------------------------------------------ D:codeIdeaProjectsjavacode2018-parent>cd javacode2018-pc D:codeIdeaProjectsjavacode2018-parentjavacode2018-pc>mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------- [INFO] Building javacode2018-pc 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ javacode2018-pc --- [INFO] com.javacode2018:javacode2018-pc:jar:1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.676 s [INFO] Finished at: 2019-11-19T15:45:08+08:00 [INFO] ------------------------------------------------------------------------
父子構件中都看不到依賴的jar包了,說明父pom.xml中dependencyManagement這些依賴的構建沒有被子模塊依賴進去。
子模塊如果想用到這些配置,可以dependencies
進行引用,引用之後,依賴才會真正的起效。
在在3個子模塊的pom.xml中加入下面配置:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> </dependencies>
我們在運行一下上面的3個命令,看效果:
D:codeIdeaProjectsjavacode2018-parent>mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ----------------< com.javacode2018:javacode2018-parent >----------------- [INFO] Building javacode2018-parent 1.0-SNAPSHOT [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ javacode2018-parent --- [INFO] com.javacode2018:javacode2018-parent:pom:1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.759 s [INFO] Finished at: 2019-11-19T15:48:28+08:00 [INFO] ------------------------------------------------------------------------ D:codeIdeaProjectsjavacode2018-parent>cd javacode2018-pc D:codeIdeaProjectsjavacode2018-parentjavacode2018-pc>mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------- [INFO] Building javacode2018-pc 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ javacode2018-pc --- [INFO] com.javacode2018:javacode2018-pc:jar:1.0-SNAPSHOT [INFO] +- org.springframework:spring-web:jar:5.2.1.RELEASE:compile [INFO] | +- org.springframework:spring-beans:jar:5.2.1.RELEASE:compile [INFO] | - org.springframework:spring-core:jar:5.2.1.RELEASE:compile [INFO] | - org.springframework:spring-jcl:jar:5.2.1.RELEASE:compile [INFO] - org.mybatis:mybatis-spring:jar:2.0.3:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.875 s [INFO] Finished at: 2019-11-19T15:48:38+08:00 [INFO] ------------------------------------------------------------------------
javacode2018-parent構件中沒有列出依賴信息,而javacode2018-pc列出了依賴信息。
大家看一下下面的截圖:

注意上面的紅框中依賴的構建沒有
version
,左邊2個紅圈中的2個向上的箭頭,表示這個是從父pom.xml中傳遞過來的,所以version可以省略。
再看一下父pom.xml截圖效果:

dependencyManagement中定義了依賴的構建,2個向下的箭頭表示被子模塊有繼承。
dependencyManagement不會引入實際的依賴,只有在子類中使用dependency
來引入父dependencyManagement
聲明的依賴之後,依賴的構建才會被真正的引入。
使用dependencyManagement來解決繼承的問題,子pom.xml中只用寫groupId,artifactId
就可以了,其他信息都會從父dependencyManagement
中聲明的依賴關係中傳遞過來,通常我們使用這種方式將所有依賴的構建在父pom.xml中定義好,子構件中只需要通過groupId,artifactId
就可以引入依賴的構建,而不需要寫version
,可以很好的確保多個子項目中依賴構件的版本的一致性,對應依賴構件版本的升級也非常方便,只需要在父pom.xml中修改一下就可以了。
單繼承問題
存在的問題及解決方案
上面講解了dependencyManagement的使用,但是有個問題,只有使用繼承的時候,dependencyManagement中聲明的依賴才可能被子pom.xml用到,如果我的項目本來就有父pom.xml了,但是我現在想使用另外一個項目dependencyManagement中聲明的依賴,此時我們怎麼辦?這就是單繼承的問題,這種情況在spring-boot、spring-cloud中會遇到,所以大家需要注意,這塊一定需要玩轉。
當我們想在項目中使用另外一個構件中dependencyManagement聲明的依賴,而又不想繼承這個項目的時候,可以在我們的項目中使用加入下面配置:
<dependencyManagement> <dependencies> <dependency> <groupId>com.javacode2018</groupId> <artifactId>javacode2018-parent</artifactId> <version>1.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> <dependency>構件2</dependency> <dependency>構件3</dependency> <dependency>構件n</dependency> </dependencies> </dependencyManagement>
上面這個配置會將javacode2018-parent
構件中dependencyManagement
元素中聲明的所有依賴導入到當前pom.xml的dependencyManagement
中,相當於把下面部分的內容:
<dependency> <groupId>com.javacode2018</groupId> <artifactId>javacode2018-parent</artifactId> <version>1.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency>
替換成了javacode2018-parent/pom.xml
中dependencyManagement元素內容,替換之後變成:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.1.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.3</version> </dependency> <dependency>構件2</dependency> <dependency>構件3</dependency> <dependency>構件n</dependency> </dependencies> </dependencyManagement>
實操案例
創建項目javacode2018-pom-import
,具體過程不演示了,坐標信息:
<groupId>com.javacode2018</groupId> <artifactId>javacode2018-pom-import</artifactId> <version>1.0-SNAPSHOT</version>
創建完畢之後,如下圖:

修改javacode2018-pom-import/pom.xml
內容,如下:
<?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.javacode2018</groupId> <artifactId>javacode2018-pom-import</artifactId> <version>1.0-SNAPSHOT</version> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> </project>
上面我們在
dependencyManagement
中聲明了2個依賴:fastjson和junit。
在javacode2018-pom-import/pom.xml
中執行mvn install
將其安裝到本地倉庫
D:codeIdeaProjectsjavacode2018-pom-import>mvn install [INFO] Scanning for projects... [INFO] [INFO] --------------< com.javacode2018:javacode2018-pom-import >-------------- [INFO] Building javacode2018-pom-import 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-pom-import --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-pom-import --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-pom-import --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode2018-pom-importsrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-pom-import --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-pom-import --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-pom-import --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-pom-importtargetjavacode2018-pom-import-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-pom-import --- [INFO] Installing D:codeIdeaProjectsjavacode2018-pom-importtargetjavacode2018-pom-import-1.0-SNAPSHOT.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pom-import1.0-SNAPSHOTjavacode2018-pom-import-1.0-SNAPSHOT.jar [INFO] Installing D:codeIdeaProjectsjavacode2018-pom-importpom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-pom-import1.0-SNAPSHOTjavacode2018-pom-import-1.0-SNAPSHOT.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.692 s [INFO] Finished at: 2019-11-19T17:23:16+08:00 [INFO] ------------------------------------------------------------------------
現在我們想在javacode2018-pc/pom.xml
中使用javacode2018-pom-import/pom.xml
的dependencyManagement
元素中定義的fastjson和junit的依賴
,而我們的javacode2019-pc
已經繼承了javacode-parent
了,maven中只能單繼承,所以沒法通過繼承的方式來實現了,那麼我們可以在javacode2019-pc/pom.xml
中加入下面配置:
<dependencyManagement> <dependencies> <dependency> <groupId>com.javacode2018</groupId> <artifactId>javacode2018-pom-import</artifactId> <version>1.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
此時可以使用fastjson的依賴了,javacode2018-pc/pom.xml
中project->dependencies
元素中加入下面配置:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency>
看一下效果:

上面的fastjson沒有指定版本號,直接可以使用,說明從
javacode2018-pom-import
傳遞過來了。
可以點擊一下上面紅圈中的箭頭,會跳到本地倉庫的javacode2018-pom-import-1.0-SNAPSHOT.pom
文件,如下:

插件管理(pluginManagement)
maven中提供了dependencyManagement來解決繼承的問題,同樣也提供了解決插件繼承問題的pluginManagement
元素,在父pom中可以在這個元素中聲明插件的配置信息,但是子pom.xml中不會引入此插件的配置信息,只有在子pom.xml中使用plugins->plugin
元素正在引入這些聲明的插件的時候,插件才會起效,子插件中只需要寫groupId、artifactId
,其他信息都可以從父構件中傳遞過來。
實操案例
在javacode2018-parent/pom.xml
中加入下面配置:
<build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <id>attach-source</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins> </pluginManagement> </build>
maven-source-plugin這個插件在上一章有介紹過,源碼打包的。 上面是將插件
maven-source-plugin
的jar-no-fork
目標綁定在default
生命周期的verify
階段,verify
階段會在default生命周期的install
周期前面執行。 下面我們看效果。
在javacode2018-pc/pom.xml所在目錄運行下面命令
D:codeIdeaProjectsjavacode2018-parentjavacode2018-pc>mvn clean install [INFO] Scanning for projects... [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------- [INFO] Building javacode2018-pc 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javacode2018-pc --- [INFO] Deleting D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctarget [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcsrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-pc --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-pc --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-pc --- [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcpom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.254 s [INFO] Finished at: 2019-11-19T16:24:39+08:00 [INFO] ------------------------------------------------------------------------
mvn clean install 會清理代碼,然後將打包構件,將構建安裝到本地倉庫,從輸入中可以看到
javacode2018-pc-1.0-SNAPSHOT.jar
被安裝到本地倉庫了。 但是沒有看到打包源碼的插件的運行,說明了javacode2018-pc
沒有從父pom.xml中繼承插件的配置信息,所以插件配置沒有起效,現在我們要讓插件起效,繼續看:
在javacode2018-pc/pom.xml中加入下面配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> </plugin> </plugins> </build>
截圖看效果:

又一個線上的箭頭,說明這個是從父pom.xml中傳遞過來了,大家仔細看一下上面的配置,插件只寫了groupId、artifactId
,其他信息都沒有寫,其他信息都可以從父pom.xml中傳遞過來,下面我們看一下插件是否起效了,運行下面命令,見證奇蹟:
D:codeIdeaProjectsjavacode2018-parentjavacode2018-pc>mvn clean install [INFO] Scanning for projects... [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------- [INFO] Building javacode2018-pc 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javacode2018-pc --- [INFO] Deleting D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctarget [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcsrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-pc --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-pc --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-source-plugin:3.2.0:jar-no-fork (attach-source) @ javacode2018-pc --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT-sources.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-pc --- [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcpom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.pom [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT-sources.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT-sources.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.477 s [INFO] Finished at: 2019-11-19T16:28:18+08:00 [INFO] ------------------------------------------------------------------------
注意上面的輸出中有
attach-source
,這個就是上面我們插件任務的id,輸出中還有javacode2018-pc-1.0-SNAPSHOT-sources.jar
信息,說明源碼也是打包成功了,最後也是上傳到了本地倉庫了。
上面演示了只用在子pom.xml中寫上插件的groupId、artifactId
就可以了,其他信息會從父pom.xml中插件的定義中傳遞過來,而子pom.xml中也可以自定義插件的這些配置,修改javacode2018-pc/pom.xml
配置,如下:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-source</id> <goals> <goal>help</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
再看一下效果:
D:codeIdeaProjectsjavacode2018-parentjavacode2018-pc>mvn clean install [INFO] Scanning for projects... [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------- [INFO] Building javacode2018-pc 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javacode2018-pc --- [INFO] Deleting D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctarget [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcsrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-pc --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-pc --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-source-plugin:3.2.0:help (attach-source) @ javacode2018-pc --- [INFO] Apache Maven Source Plugin 3.2.0 The Maven Source Plugin creates a JAR archive of the source files of the current project. This plugin has 7 goals: source:aggregate Aggregate sources for all modules in an aggregator project. source:generated-test-jar This plugin bundles all the test sources into a jar archive. source:help Display help information on maven-source-plugin. Call mvn source:help -Ddetail=true -Dgoal=<goal-name> to display parameter details. source:jar This plugin bundles all the sources into a jar archive. source:jar-no-fork This goal bundles all the sources into a jar archive. This goal functions the same as the jar goal but does not fork the build and is suitable for attaching to the build lifecycle. source:test-jar This plugin bundles all the test sources into a jar archive. source:test-jar-no-fork This goal bundles all the test sources into a jar archive. This goal functions the same as the test-jar goal but does not fork the build, and is suitable for attaching to the build lifecycle. [INFO] [INFO] --- maven-source-plugin:3.2.0:jar-no-fork (attach-source) @ javacode2018-pc --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT-sources.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-pc --- [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcpom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.pom [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT-sources.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT-sources.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.752 s [INFO] Finished at: 2019-11-19T16:41:21+08:00 [INFO] ------------------------------------------------------------------------
輸出中有下面2行:
[INFO] --- maven-source-plugin:3.2.0:help (attach-source) @ javacode2018-pc --- [INFO] --- maven-source-plugin:3.2.0:jar-no-fork (attach-source) @ javacode2018-pc ---
說明maven-source-plugin
插件執行了2個目標:help
和jar-no-fork
。此時父子pom.xml中插件配置信息合併了,所以出現了2個目標。具體最終javacode2018-pc/pom.xml
中的內容是什麼樣的,可以通過下面這個命令看到:
mvn help:effective-pom
上面這個命令大家最好去看一下效果,當pom.xml中存在複雜的關係的時候,可以通過這個命令解析得到這個構件最終pom.xml的內容。
聚合與繼承的關係
前面已經詳解了聚合和繼承,想必大家對這塊也有了自己的理解。
聚合主要是為了方便多模塊快速構建。
而繼承主要是為了重用相同的配置。
對於聚合來說,聚合模塊是知道被聚合模塊的存在的,而被聚合模塊是感知不到聚合模塊的存在。
對於繼承來說,父構件是感知不到子構件的存在,而子構件需要使用parent
來引用父構件。
兩者的共同點是,聚合模塊和繼承中的父模塊的package屬性都必須是pom類型的,同時,聚合模塊和父模塊中的除了pom.xml,一般都是沒有什麼內容的。
實際使用是,我們經常將聚合和繼承一起使用,能同時使用到兩者的優點。
下面我們在javacode2018-parent
中加入聚合的配置:
<modules> <module>javacode2018-pc</module> <module>javacode2018-h5</module> <module>javacode2018-api</module> </modules>
javacode20180-parent/pom.xml目錄運行一下mvn install,看看效果:
D:codeIdeaProjectsjavacode2018-parent>mvn install [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] javacode2018-parent [pom] [INFO] javacode2018-pc [jar] [INFO] javacode2018-h5 [jar] [INFO] javacode2018-api [jar] [INFO] [INFO] ----------------< com.javacode2018:javacode2018-parent >---------------- [INFO] Building javacode2018-parent 1.0-SNAPSHOT [1/4] [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-parent --- [INFO] Installing D:codeIdeaProjectsjavacode2018-parentpom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-parent1.0-SNAPSHOTjavacode2018-parent-1.0-SNAPSHOT.pom [INFO] [INFO] ------------------< com.javacode2018:javacode2018-pc >------------------ [INFO] Building javacode2018-pc 1.0-SNAPSHOT [2/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-pc --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcsrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-pc --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-pc --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-pc --- [INFO] [INFO] --- maven-source-plugin:3.2.0:help (attach-source) @ javacode2018-pc --- [INFO] Apache Maven Source Plugin 3.2.0 The Maven Source Plugin creates a JAR archive of the source files of the current project. This plugin has 7 goals: source:aggregate Aggregate sources for all modules in an aggregator project. source:generated-test-jar This plugin bundles all the test sources into a jar archive. source:help Display help information on maven-source-plugin. Call mvn source:help -Ddetail=true -Dgoal=<goal-name> to display parameter details. source:jar This plugin bundles all the sources into a jar archive. source:jar-no-fork This goal bundles all the sources into a jar archive. This goal functions the same as the jar goal but does not fork the build and is suitable for attaching to the build lifecycle. source:test-jar This plugin bundles all the test sources into a jar archive. source:test-jar-no-fork This goal bundles all the test sources into a jar archive. This goal functions the same as the test-jar goal but does not fork the build, and is suitable for attaching to the build lifecycle. [INFO] [INFO] --- maven-source-plugin:3.2.0:jar-no-fork (attach-source) @ javacode2018-pc --- [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-pc --- [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.jar [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pcpom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT.pom [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-pctargetjavacode2018-pc-1.0-SNAPSHOT-sources.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-pc1.0-SNAPSHOTjavacode2018-pc-1.0-SNAPSHOT-sources.jar [INFO] [INFO] ------------------< com.javacode2018:javacode2018-h5 >------------------ [INFO] Building javacode2018-h5 1.0-SNAPSHOT [3/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-h5 --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-h5 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-h5 --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode2018-parentjavacode2018-h5srctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-h5 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-h5 --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-h5 --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-parentjavacode2018-h5targetjavacode2018-h5-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-h5 --- [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-h5targetjavacode2018-h5-1.0-SNAPSHOT.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-h51.0-SNAPSHOTjavacode2018-h5-1.0-SNAPSHOT.jar [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-h5pom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-h51.0-SNAPSHOTjavacode2018-h5-1.0-SNAPSHOT.pom [INFO] [INFO] -----------------< com.javacode2018:javacode2018-api >------------------ [INFO] Building javacode2018-api 1.0-SNAPSHOT [4/4] [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javacode2018-api --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ javacode2018-api --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javacode2018-api --- [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:codeIdeaProjectsjavacode2018-parentjavacode2018-apisrctestresources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ javacode2018-api --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javacode2018-api --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ javacode2018-api --- [INFO] Building jar: D:codeIdeaProjectsjavacode2018-parentjavacode2018-apitargetjavacode2018-api-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ javacode2018-api --- [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-apitargetjavacode2018-api-1.0-SNAPSHOT.jar to C:UsersThink.m2repositorycomjavacode2018javacode2018-api1.0-SNAPSHOTjavacode2018-api-1.0-SNAPSHOT.jar [INFO] Installing D:codeIdeaProjectsjavacode2018-parentjavacode2018-apipom.xml to C:UsersThink.m2repositorycomjavacode2018javacode2018-api1.0-SNAPSHOTjavacode2018-api-1.0-SNAPSHOT.pom [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for javacode2018-parent 1.0-SNAPSHOT: [INFO] [INFO] javacode2018-parent ................................ SUCCESS [ 0.416 s] [INFO] javacode2018-pc .................................... SUCCESS [ 2.654 s] [INFO] javacode2018-h5 .................................... SUCCESS [ 0.262 s] [INFO] javacode2018-api ................................... SUCCESS [ 0.225 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.827 s [INFO] Finished at: 2019-11-19T17:51:42+08:00 [INFO] ------------------------------------------------------------------------
上篇文章中留下的2個問題
問題1
下面這個配置是幹什麼的?給哪個插件使用的?
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
編譯代碼的時候,涉及到資源文件和測試資源文件的拷貝,拷貝文件的時候涉及到文件的編碼,這個是設置文件的編碼為UTF-8
格式的。
我們在上篇文章的maven-chat06
項目的目錄中執行mvn compile
命令,效果如下:
D:codeIdeaProjectsmaven-chat06>mvn compile [INFO] Scanning for projects... [INFO] [INFO] -------------------< com.javacode2018:maven-chat06 >-------------------- [INFO] Building maven-chat06 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-chat06 --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-chat06 --- [INFO] Nothing to compile - all classes are up to date [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.179 s [INFO] Finished at: 2019-11-19T17:57:27+08:00 [INFO] ------------------------------------------------------------------------
可以看到上面有這樣的輸出:
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-chat06 --- [INFO] Using 'UTF-8' encoding to copy filtered resources.
從上面可以看出maven-resources-plugin
插件的resources
目標中會使用這個編碼的配置,我們來看一下這個目標具體參數配置,我們截取了部分輸出,如下:
D:codeIdeaProjectsmaven-chat06>mvn help:describe -Dplugin=resources -Dgoal=resources -Ddetail [INFO] Scanning for projects... [INFO] [INFO] -------------------< com.javacode2018:maven-chat06 >-------------------- [INFO] Building maven-chat06 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-help-plugin:3.2.0:describe (default-cli) @ maven-chat06 --- [INFO] Mojo: 'resources:resources' resources:resources Description: Copy resources for the main source code to the main output directory. Always uses the project.build.resources element to specify the resources to copy. Implementation: org.apache.maven.plugin.resources.ResourcesMojo Language: java Bound to phase: process-resources Available parameters: delimiters Set of delimiters for expressions to filter within the resources. These delimiters are specified in the form 'beginToken*endToken'. If no '*' is given, the delimiter is assumed to be the same for start and end. So, the default filtering delimiters might be specified as: <delimiters> <delimiter>${*}</delimiter> <delimiter>@</delimiter> </delimiters> Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can). encoding (Default: ${project.build.sourceEncoding}) User property: encoding The character encoding scheme to be applied when filtering resources.
注意上面輸出中最後的一部分,如下:
encoding (Default: ${project.build.sourceEncoding}) User property: encoding The character encoding scheme to be applied when filtering resources.
encoding這個參數用來指定編碼的,默認值是${project.build.sourceEncoding}
,也可以通過encoding
用戶屬性來設置。
所以這個設置編碼的還有下面3種寫法,共四種:
pom.xml中2種: <encoding>UTF-8</encoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> mvn命令中2種: mvn compile -Dencoding=UTF-8 mvn compile -Dproject.build.sourceEncoding=UTF-8
問題2
mvn test運行測試用例的時候,測試用例類名的寫法默認是有規則的,這些規則有人知道么?從哪裡可以看到這些規則?如何自定義?
我們在上一篇中的maven-chat06
項目中執行mvn test
,看看效果:
D:codeIdeaProjectsmaven-chat06>mvn test [INFO] Scanning for projects... [INFO] [INFO] -------------------< com.javacode2018:maven-chat06 >-------------------- [INFO] Building maven-chat06 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-chat06 --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-chat06 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-chat06 --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-chat06 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-chat06 --- [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.411 s [INFO] Finished at: 2019-11-19T18:07:52+08:00 [INFO] ------------------------------------------------------------------------
可以看到下面這行:
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-chat06 ---
表示運行測試使用的是插件maven-surefire-plugin
的test
目標。
我們看看這個目標詳細參數,只列出部分信息,如下:
D:codeIdeaProjectsmaven-chat06>mvn help:describe -Dplugin=surefire -Dgoal=test -Ddetail [INFO] Scanning for projects... [INFO] [INFO] -------------------< com.javacode2018:maven-chat06 >-------------------- [INFO] Building maven-chat06 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-help-plugin:3.2.0:describe (default-cli) @ maven-chat06 --- [INFO] Mojo: 'surefire:test' surefire:test Description: Run tests using Surefire. Implementation: org.apache.maven.plugin.surefire.SurefirePlugin Language: java Bound to phase: test Available parameters: includes A list of <include> elements specifying the tests (by pattern) that should be included in testing. When not specified and when the test parameter is not specified, the default includes will be <includes> <include>**/IT*.java</include> <include>**/*IT.java</include> <include>**/*ITCase.java</include> </includes> Each include item may also contain a comma-separated sublist of items, which will be treated as multiple <include> entries. This parameter is ignored if the TestNG suiteXmlFiles parameter is specified. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4.458 s [INFO] Finished at: 2019-11-19T18:10:09+08:00 [INFO] ------------------------------------------------------------------------
可以看到上面有個includes
參數,可以用來配置需要運行的測試用例,可以配置通配符的方式。
上面還有一段信息:
Implementation: org.apache.maven.plugin.surefire.SurefirePlugin
上面這部分列出了這個目標的具體實現類是SurefirePlugin
。
那麼我們可以到本地倉庫中看一下這個構件的源碼,構件的坐標是:
<groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12.4</version>
打開org.apache.maven.plugin.surefire.SurefirePlugin
的源碼,會找到下面代碼:
protected String[] getDefaultIncludes() { return new String[]{ "**/Test*.java", "**/*Test.java", "**/*TestCase.java" }; }
這部分代碼就是我們測試用例默認需要滿足的格式,你創建的測試用例默認情況下必須滿足上面這3種格式,否則,測試用例不會被mvn test
執行。
總結
- 需要掌握聚合的使用
- 掌握繼承的使用
- 掌握單繼承問題解決方案
- 掌握依賴管理和插件管理的使用
還是那句話,建議大家下去了多練練,都操作一遍,加深理解!
Maven系列目錄
- Maven系列:第1篇:Maven未出世前,我們那些痛苦的經歷!
- Maven系列第2篇:安裝、配置、mvn運行過程詳解
- Maven系列第3篇:詳解maven解決依賴問題
- Maven系列第4篇:倉庫詳解
- Maven系列第5篇:私服詳解
- Maven系列第6篇:生命周期和插件詳解,高手必備!