Maven POM 檔案中的中的繼承(Inheritance)和 聚合(Aggregation)- IDEA 和 Eclipse 中多模組專案的 Maven 組織方法
Maven POM 檔案中的繼承和聚合(Inheritance & Aggregation)
之前在 IDEA 裡建了一個專案專門用來學習,每個知識點都建立一個相應的模組,方便學習和檢視。今天在建第二個模組的時候發現,這個模組很多的 Maven 依賴和第一個模組相同,按照我之前一個專案僅一個模組的做法,那肯定是要把依賴再複製貼上一遍。但是在同一個專案裡面,隨著模組不斷增加,不能每次都複製貼上吧,而且模組都是 Maven 工程,可以利用 Maven 來對這些模組進行管理。帶著這種想法,我去官網學習了下 POM 檔案中的繼承和聚合。
POM
POM (Project Object Model),在我們的 Maven 專案中表現出來的就是 pom.xml 檔案,是對整個 Maven 專案的組織管理檔案。
Super POM
我們建立 Maven 專案的時候,或是手動建立或是自動建立,都會有一個固定的檔案目錄結構,那為什麼必須是按照這個結構來呢?新增依賴後,專案自動會從 Maven 中央倉庫下載相關的 jar 包,它是在什麼地方定義這個倉庫地址的?這些問題的答案就是 Super POM。我們在專案中建立的 POM 檔案都是繼承自這個 Super POM,它是 Maven 專案的預設 POM。下面是 Maven 2.1.x 版本的 Super POM,能看到其中定義了很多預設的配置。
<project>
<modelVersion>4.0.0</modelVersion >
<name>Maven Default Project</name>
<repositories>
<repository>
<id>central</id>
<name>Maven Repository Switchboard</name>
<layout>default</layout>
<url>http://repo1.maven.org/maven2</url>
<snapshots >
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<!-- TODO: MNG-3731 maven-plugin-tools-api < 2.4.4 expect this to be relative... -->
<scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.3.1</version>
</plugin>
<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.2</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.4.3</version>
</plugin>
<plugin>
<artifactId>maven-rar-plugin</artifactId>
<version>2.2</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.0-beta-8</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>2.0-beta-7</version>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.0.4</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.3</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-alpha-2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Minimal POM
既然 Super POM 中已經有很多預設的 Maven 配置,那麼對於我們自己建立的 POM 檔案,如果不需要新增額外的功能,只需要定義最小配置即可。參考如下
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
即專案的基本資訊,其中<modelVersion>
應該被設為4.0.0
,<groupId>
、<artifactId>
、<version>
提供了專案組織id、專案id以及專案版本號。
專案繼承
Super POM 就是一個典型的 POM 繼承的例子。我們也可以自己定義模組之間的繼承方式,從父模組的 POM 配置中繼承配置資訊,子模組就不再需要進行重複的配置。
這裡有兩個模組(或者稱為構件:artifact),my-app 和 my-module 模組。其中 my-module 模組繼承自 my-app 模組,即 my-app 模組是 my-module 模組的父模組。根據兩個模組之間不同的組織結構,有兩種不同的配置方法。
對於 IDEA 來說,可以建立一個 Maven 工程,再在其中新增 Maven 模組,配置模組繼承工程的 POM ,這樣的話專案目錄結構就是 Example 1。也可以建立一個空的工程,在其中新增多個 Maven 模組,配置模組之間的 POM 關係實現繼承,這樣專案目錄結構就是 Example 2。對於 Eclipse 來說,就只能建立 Example 2 的目錄結構了。
- 第一種結構 Example 1:
my-app
|-- my-module
| `-- pom.xml
`-- pom.xml
my-module 模組是 my-app 模組的一部分,處於 my-app 模組的根目錄下,與 my-app 的 pom.xml 檔案平級。這裡可以通過在子模組 my-module 裡的 POM 中新增一下內容實現繼承。
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
這裡在<project>
中指定了<parent>
元素,其中聲明瞭父模組的組織資訊。如果希望子模組繼承父模組的<groupId>
和<version>
,刪掉子模組中的<groupId>
和<version>
即可。
- 第二種結構 Example 2:
.
|-- my-module
| `-- pom.xml
`-- my-app
`-- pom.xml
這種結構中,my-module 和 my-app 模組在相同的目錄下,兩者之間處於平級關係。Eclipse 中各個專案之間就是這種目錄層級關係。這種情況下我們可以新增一個<relativePath>
元素到子模組的<parent>
中,來實現繼承關係,而其值就是 POM 檔案的相對路徑。
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../my-app/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
這裡 my-module 繼承了 my-app 的 <groupId>
和<version>
,這樣也就實現了繼承。
POM 中多模組專案的聚合和繼承針對的都是以上兩種目錄結構的專案。
專案聚合
聚合與繼承相似,不同的是繼承方式配置的是子模組的 POM,而聚合方式配置的是父模組的 POM(即 pom.xml 檔案)。操作步驟如下
1. 將父模組 POMs 的 packaging 值設為 "pom"
2. 在父模組 POM 中指定子模組的路徑
- 第一種結構 Example 1:
my-app
|-- my-module
| `-- pom.xml
`-- pom.xml
針對這種結構,我們在 my-app 模組(父模組)的 POM 檔案中新增<modules>
元素進行配置
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>my-module</module>
</modules>
</project>
注意,在聚合方式中,父模組的打包方式<packaging>
發生了改變,這裡是pom
而不再是war
。<module>
元素中使用的是子模組相對於父模組的路徑。
通過這種配置方式,在 my-app 上執行的 Maven 命令也會在 my-module 上執行。
- 第二種結構 Example 2:
.
|-- my-module
| `-- pom.xml
`-- my-app
`-- pom.xml
參考第一種結構,我們使用了<module>
元素中模組之間的相對路徑,那麼對於第二種結構,我們修改下相對路徑即可。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>../my-module</module>
</modules>
</project>
專案繼承和聚合的組合使用
首先說一下繼承和聚合使用的場景:
繼承:有多個 Maven 專案,它們具有相似的 POM 配置資訊。我們可以重構所有專案,將相似的配置資訊抽取出來,放到新建立的父專案裡,然後讓所有 Maven 專案繼承父專案,這樣就是繼承的用法。
聚合:有一組專案,它們同時編譯或執行,那我們可以建立一個父專案,將這組專案宣告為父專案的多個子模組,這樣的話,我們就只用編譯或執行父專案即可。這是聚合的使用場景。
我們在實際開發過程中,會組合使用繼承和聚合。比如說,我們需要開發一個專案,這個專案由多個模組組成,這些模組用到的 POM 配置資訊相似,而且模組之間會有依賴關係,某個模組依賴於另外一個模組才能正常執行。這樣情況我們就可以組合使用繼承和聚合,能大大的減少專案的配置和管理成本。
使用繼承和聚合,需要遵循3個規定:
1. 在每個子 POM 中指定它們的父 POM
2. 將父 POMs 打包方式設為 "pom"
3. 在父 POM 中指定子模組的路徑
我們使用第二種結構作為示例。第一種結構與其相似,去掉 <relativePath>
即可。
my-app 專案中:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>../my-module1</module>
<module>../my-module2</module>
<module>../my-module3</module>
</modules>
</project>
my-module1 專案中:
<project>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../my-app/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module1</artifactId>
</project>
my-module2、my-module3 專案配置與 my-module1 相似,不列出。
實際開發過程中,多模組的管理方式可以是繼承和聚合的組合使用。我在之前建立的用於學習的專案,可以僅僅使用繼承。其中為了將 POM 配置資訊獨立出來,可以新建一個模組,這個模組只有 POM 配置資訊,其他的模組依賴這個模組,即可實現 Maven 依賴的複用。
專案中的變數
Maven 允許在 POM 中使用自定義的和預設的變數。自定義變數的方式:
<properties>
<spring.version>4.3.6.RELEASE</spring.version>
</properties>
使用方式:
<version>${spring.version}</version>
實戰:多模組專案 POM 示例
專案模組組織關係:
專案有一個核心模組,提供了專案其他模組執行時的各種元件。依賴於這個核心模組,專案提供了 瀏覽器 和 App 兩種基礎服務後臺。在 瀏覽器 後臺上,構建一個 Demo 專案,用於展示專案開發成果。
使用 Maven 管理:
首先構建一個父模組,所有的模組都繼承這個父模組
parent-module:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>big-project</groupId>
<artifactId>parent-module</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<p.version>1.0-SNAPSHOT</p.version>
</properties>
...
<modules>
<module>../core-module</module>
<module>../browser-module</module>
<module>../app-module</module>
<module>../demo-module</module>
</modules>
</project>
建好後,和其他模組的目錄結構關係如下:
.
|-- parent-module
`-- pom.xml
|-- core-module
`-- pom.xml
|-- app-module
`-- pom.xml
|-- browser-module
`-- pom.xml
|-- demo-module
`-- pom.xml
其他模組 POM 配置如下
core-module:
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>core-module</artifactId>
<parent>
<groupId>big-project</groupId>
<artifactId>parent-module</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../parent-module</relativePath>
</parent>
...
</project>
app-module:
<project>
<artifactId>app-module</artifactId>
<parent>
<groupId>big-project</groupId>
<artifactId>parent-module</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../parent-module</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>big-project</groupId>
<artifactId>core-module</artifactId>
<version>${p.version}</version>
</dependency>
...
</dependencies>
</project>
browser-module:
<project>
<artifactId>browser-module</artifactId>
<parent>
<groupId>big-project</groupId>
<artifactId>parent-module</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../parent-module</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>big-project</groupId>
<artifactId>core-module</artifactId>
<version>${p.version}</version>
</dependency>
...
</dependencies>
</project>
demo-module:
<project>
<artifactId>demo-module</artifactId>
<parent>
<groupId>big-project</groupId>
<artifactId>parent-module</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../parent-module</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>big-project</groupId>
<artifactId>browser-module</artifactId>
<version>${p.version}</version>
</dependency>
...
</dependencies>
</project>
在 parent-module 中,配置了多個 <module>
元素,其他的模組也相應地配置了 <parent>
資訊,這樣在編譯或執行 parent-module 時,其他模組也都進行了編譯或執行。
app-module 和 browser-module 均依賴於 core-module,均使用了 <dependency>
來完成這個依賴。
demo-module 依賴於 browser-module,使用<dependency>
來完成這個依賴。
參考資料:
相關推薦
Maven POM 檔案中的中的繼承(Inheritance)和 聚合(Aggregation)- IDEA 和 Eclipse 中多模組專案的 Maven 組織方法
Maven POM 檔案中的繼承和聚合(Inheritance & Aggregation) 之前在 IDEA 裡建了一個專案專門用來學習,每個知識點都建立一個相應的模組,方便學習和檢視。今天在建第二個模組的時候發現,這個模組很多的 Mave
Maven pom檔案中屬性變數總結
1.內建屬性:${basedir}表示當前專案根目錄; ${version}表示當前專案版本。 2.POM屬性: ${project.artifactId} 等價於元素的值,個人理解,本質上每個標籤底層是通過物件的引用實現,也同樣存在繼承特性(僅僅是個人理解,供
Maven POM檔案中依賴與外掛的配置
POM(Project Object Model)是 Maven 工程的工作基礎,以 pom.xml 的形式存在於專案中,在這裡配置構建工程的詳細資訊。它為大多數專案都預先配置了一些預設值,如構建目錄 build,原始碼目錄 src/main/java,測試原始
Springboot整合dubbo構建maven多模組專案(一)- 專案建立和pom.xml中jar包配置
以前一直用Spring作為容器構建專案,但是看到Spring官網一直在推Springboot,最重要的是Springboot確實避免自己尋找多個jar包(大多數情況下,可能自己都不記得該引入哪些jar包)和jar包之間衝突的問題,同時省掉了在整合其他框架時候
springboot多模組專案,引用子專案的mapper中的xml檔案
springboot多模組專案,引用子專案的mapper中的xml檔案,一直引用不到, 提示: Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): utopi
(原創)超詳細一步一步在eclipse中配置Struts2環境,無基礎也能看懂
(原創)超詳細一步一步在eclipse中配置Struts2環境,無基礎也能看懂 1. 在官網https://struts.apache.org下載Struts2,建議下載2.3系列版本。從圖中可以看出,既可以分開下載子檔案,又可以一次全部下載。 這裡我後
史上最全的Maven Pom檔案標籤詳解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
Spring SpringMVC Maven pom檔案
<dependencies> <!--Spring支援包--> <!-- https://mvnrepository.com/artifact/commons-l
Maven實戰(三)——多模組專案的POM重構
在本專欄的上一篇文章POM重構之增還是刪中,我們討論了一些簡單實用的POM重構技巧,包括重構的前提——持續整合,以及如何通過新增或者刪除內容來提高POM的可讀性和構建的穩定性。但在實際的專案中,這些技巧還是不夠的,特別值得一提的是,實際的Maven專案基本都是多模組的,如果僅
UML中類之間的幾種關係,關聯(association),聚合(Aggregation),組合(Composition)
類之間可能存在以下幾種關係:關聯(association)、依賴(dependency)、聚合(Aggregation,也有的稱聚集)、組合(Composition)、泛化(generalization,也有的稱繼承)、實現(Realization)。 關聯是指兩個類之間存在某種特定的對應關係,例如客戶和訂
Maven學習總結——IDEA中使用Maven構建多模組專案
在平時的Javaweb專案開發中為了便於後期的維護,我們一般會進行分層開發,最常見的就是分為domain(域模型層)、dao(資料庫訪問層)、service(業務邏輯層)、web(表現層),這樣分層之後,各個層之間的職責會比較明確,後期維護起來也相對比較容易,今天我們就是使用Maven來構建以上的各個層
IDEA中建立Web聚合專案(Maven多模組專案)
1、建立parent專案 2、建立子模組 3、這樣一個project就建立好了,刪除沒有用的src 4、當前結構 5、這個時候建立的不管是child1還是child2都是普通的Java專案,而不是JavaWeb專案,在一個JavaWeb專案中,我們的模組可能分為
IntelliJ IDEA中建立Web聚合專案(Maven多模組專案)
Eclipse用多了,IntelliJ中建立Maven聚合專案可能有小夥伴還不太熟悉,我們今天就來看看。 IntelliJ中建立普通的Java聚合專案相對來說比較容易,不會涉及到web操作,涉及到web的話會有一點點麻煩。我們來一步一步看下。 環境:In
如何在Eclipse/Myeclipse/Scala IDEA for Eclipse 中正確刪除已經下載過的外掛(圖文詳解)
不多說,直接上乾貨! 見 第一步 :在選單欄中,找到help-------install new software 第二步,需要注意了,注意看圖。紅色區域標註的already installed? 點選進去,找到你需要要刪除的軟體,
Maven權威指南(續)之多模組專案構建及POM優化
在《Maven權威指南》部分I中,第6、7章介紹了多模組專案及多模組企業級專案的構建思想。對於多模組的情況,無論是簡單的或是企業級的,對於POM來說,重點就是分析處理好父POM與子POM之間的關係,包括依賴管理(DependencyManagement)、外掛管理(Plu
IntelliJ IDEA中建立Web聚合專案(Maven多模組專案)詳細版本!!
Eclipse用多了,IntelliJ中建立Maven聚合專案可能有小夥伴還不太熟悉,我們今天就來看看。 IntelliJ中建立普通的Java聚合專案相對來說比較容易,不會涉及到web操作,涉及到web的話會有一點點麻煩。我們來一步一步看下。環境:IntelliJ IDEA
Maven多模組專案中應用maven-tomcat-plugin熱部署
我這個專案是用maven管理的一個多模組的專案,大概結構是 aaa -Business -Core -Framework -Web aaa是pom專案,Web是war專案,其它的是jar 一開始我是在Web裡面配置了tomcat的
maven pom檔案詳解
1<project xmlns="http://maven.apache.org/POM/4.0.0 " 2 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " 4 5
Maven POM檔案、多模組以及依賴關係
一、POM.XML 1、ProjectObject Model:專案物件模型 2、基本項: project:pom.xml的頂級元素。groupId:指出建立這個工程的組織或團隊的唯一標識。plugins:外掛。artifactId:基本名稱。packaging:型別(如J
idea(二)--idea中建立多模組專案、maven多模組開發
一、idea中建立多模組專案(多工程同時開發) 熟悉eclipse、myeclipse的人都知道,eclipse、myeclipse中都有工作的空間(workspace)的概念,一個workspace中可以建立多個project,即可同時開啟多個專案進行開發。然而,遺憾的是