Maven中的聚合與繼承
1、聚合
一個帶有模組的專案稱為“多模組”或“聚合器”專案。模組是POM
列出的專案,並作為一個組執行。一個pom
打包的專案可以通過將它們作為模組來聚合一組專案的構建,這些模組是這些專案的目錄或pom
檔案的相對路徑。
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<packaging>pom</packaging>
<modules>
<module>my-project</module>
<module >another-project</module>
<module>third-project/pom-example.xml</module>
</modules>
</project>
在列出模組時,您不需要考慮模組間的依賴關係,也就是說,POM給出的模組的順序並不重要。Maven將在拓撲上對模組進行排序,這樣依賴項總是在依賴模組之前構建。
繼承和聚合建立了一個良好的動態,通過一個單一的高階POM來控制構建。你經常會看到既有繼承又有聚合的專案。例如,整個maven核心都是通過一個基本的POM org.apache.maven:maven
mvn compile
。然而,儘管就整個POM專案而言,一個聚合專案和一個繼承專案是不一樣的,不應該被混淆。一個POM專案可能來自於繼承但不是必須的——它還可能是其它任何型別的聚合模組。相反,一個POM專案可能只涉及到聚合而不涉及到繼承。
下面我們舉例來說明,之前的文章中,我們已經成功的建立了兩個Maven專案,一個是my-app
,另一個是maven-parent
,這兩個專案都是採用的繼承的模式,現在我們可以用聚合的方式將其組合成一體,比如說將maven-parent
聚合到my-app
中,具體的做法是修改my-app
中的父類pom.xml
即可。
my-app
中的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>myapp1</module>
<module>myapp2</module>
<module>myapp3</module>
<module>myapp4</module>
<module>myapp5</module>
<module>myapp6</module>
<module>my-app-site</module>
<module>my-webapp</module>
<module>maven-parent</module>
</modules>
<name>my-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
通過這樣的變化,它們就成功的聚合到了一起,通過在my-app
中的pom.xml
執行相應的構建,其所聚合的專案maven-parent
也會被一起構建。
詳細的程式碼可以參考下面的連結:
2、繼承
在之前的文章中,我就已經多少談到了Maven的繼承,在這裡我重點談一下Maven的繼承原則,在Maven中一共有兩大繼承原則。
其一是:短路優先原則
我們假設有專案D,專案E,專案F三個專案,在專案D,和專案E中都存在一個類Say
,它們的原始碼如下:
專案D中的類Say:
package com.lyc;
public class Say {
public String say(){
return "D";
}
}
專案E中的類Say:
package com.lyc;
public class Say {
public String say(){
return "E";
}
}
在專案E中存在測試類SayTest
,在專案F中也存在測試類SayTest
,它們的原始碼都相同,都如下:
專案E、F中的類SayTest
:
package com.lyc;
import org.junit.Test;
public class SayTest {
@Test
public void test(){
Say say = new Say();
System.out.println(say.say());
}
}
由於我們知道,Maven允許繼承,在這種情況下,F依賴了E,E又依賴了D,這樣在執行F中的SayTest
類時,我們根據最短路徑原則不難知道,在F中執行的是輸出專案E中的Say類,此時我們輸出為E。
當我們在執行專案E中的SayTest
類時,其輸出的也是E,這也同樣不違反該定律,因為畢竟呼叫自身的Say
,類要比呼叫依賴的Say類依賴路徑更短。
詳細的原始碼如下:
其二是:誰先宣告,先解析誰
這個比較好理解,就是我們假設現在有三個專案,分別為專案H、專案I、專案J三個專案,現在在專案H,和專案I中都存在類Say
,然後在專案J中存在測試類SayTest
,下面是專案J中的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">
<parent>
<artifactId>maven-parent3</artifactId>
<groupId>com.lyc</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>J</artifactId>
<packaging>jar</packaging>
<name>J</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.lyc</groupId>
<artifactId>H</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.lyc</groupId>
<artifactId>I</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
在專案J中執行測試類SayTest
,根據誰先宣告,先解析誰的原理,由於專案H在專案J中優先宣告,因而在專案J中呼叫SayTest
時輸出的內容為“H”。
專案的詳細原始碼如下: