Maven繼承與聚合詳解及作用介紹
一、繼承
引言
繼承關系可以對不同模塊的依賴版本做統一管理,因為子模塊中的依賴基本都繼承於父模塊,父模塊中指定哪個版本,子模塊就繼承哪個版本,可以有效避免不同模塊可能采用不同版本的依賴時產生的沖突
1. 繼承關系的實現
(1)parent 模塊設置
parent 模塊即父模塊,由於父模塊隻是為瞭給子模塊提供依賴,所以父模塊中隻需要一個 pom.xml 文件即可。父模塊的打包方式必須設置為 pom(默認打包方式是 jar)
<groupId>com.mzz</groupId> <artifactId>parent-maven</artifactId> <version>1.0-SNAPSHOT</version> <!-- 設置打包方式為 pom --> <packaging>pom</packaging>
隻要設置瞭 packaging 屬性為 pom,這個模塊就可以作為 parent 模塊被繼承瞭
(2)子模塊設置
子模塊中隻要設置瞭 parent 標簽,就可以建立繼承關系。
所以繼承主要體現在子模塊,parent 模塊是感受不到繼承關系的,也無法從 parent 模塊中看出哪些模塊繼承瞭自己。
另外繼承關系建議以後,如果子模塊與父模塊處於同一 groupId 下,那麼子模塊可以不寫 groupId
<!--<groupId>com.mzz</groupId>--> <artifactId>project-dao</artifactId> <version>1.0-SNAPSHOT</version> <parent> <!-- parent 模塊的坐標與版本 --> <groupId>com.mzz</groupId> <artifactId>parent-maven</artifactId> <version>1.0-SNAPSHOT</version> <!-- parent 模塊的相對路徑 --> <relativePath>../parent-maven/pom.xml</relativePath> </parent>
對 relativePath 屬性做一些補充:
- relativePath 可以省略,前提是 parent 模塊已經 install 至倉庫,否則子模塊無法定位到 parent,不能通過編譯
- 相對路徑最後可以不寫 pom.xml,隻定位到父模塊的文件夾也可以
2. 依賴配置
(1)必須繼承的依賴
parent 模塊中聲明的依賴便是子模塊必須繼承的依賴,子模塊中不必聲明便從父模塊中繼承瞭這些依賴
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.20.RELEASE</version> </dependency> <!-- 省略瞭其他依賴的聲明 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> <!-- scope 屬性也會被繼承 --> </dependency> <dependencies>
如上圖,可見子模塊中未聲明依賴就繼承瞭 parent 中的所有依賴
(2)有選擇地繼承依賴
parent 模塊中設置依賴管理 dependencyManagement 後,在其中聲明的依賴就是供子模塊選擇的依賴。子模塊需要哪些依賴,必須在子模塊中聲明依賴,但不需要註明 version,因為版本由 parent 來指定。
<!-- parent 模塊 --> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.10.RELEASE</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement>
<!-- 子模塊聲明依賴 --> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> </dependencies>
如果子模塊聲明的依賴有 version 屬性,那麼這個依賴並不繼承自 parent
另外,parent 模塊聲明在 dependencyManagement 中的依賴並不被 parent 模塊所依賴
(3)插件繼承
插件的繼承規則和設置方法與前面的依賴極為相似,同樣也有插件管理 pluginManagement,與 dependencyManagement 類似,這裡給出一個 parent 中設置的樣例模板
<build> <plugins> <!-- 聲明必須繼承的插件 --> </plugins> <pluginManagement> <plugins> <!-- 聲明可供選擇是否繼承的插件 --> </plugins> </pluginManagement> </build>
二、聚合
引言
聚合就是指將多個模塊組織成一個整體,同時進行項目的構建工作。
使用聚合可以避免分模塊開發時的一些問題,比如某個模塊更新瞭一些內容,但其它已經構建好的模塊不會進行更新,將所有模塊聚合之後,隻對聚合模塊進行構建就會對所有模塊都進行構建,能夠及時的發現問題
實現聚合
聚合模塊也被稱為 root 模塊,同樣是一個隻需要 pom.xml 文件的項目,隻要設置瞭 modules 標簽,再將聚合的模塊添加進去,即可實現聚合
<modules> <!-- module 屬性中寫明被聚合模塊的相對路徑 --> <module>../project-pojo</module> <module>../project-dao</module> <module>../project-service</module> </modules>
如上例,將 pojo,dao 和 service 三個模塊進行瞭聚合,隻要對聚合模塊進行構建,這三個模塊也會被一起構建
聚合隻體現在聚合模塊,被聚合的模塊也無法感知自身被誰所聚合
三、繼承與聚合的合並
繼承是的 parent 模塊和聚合時的 root 模塊都隻有 pom.xml,因為他們都是設計型模塊,不包含實際的模塊內容。事實上,繼承與聚合經常被合並在一起使用,父模塊(parent)也作為聚合模塊(root)使用,隻需要在父模塊中加入 modules 屬性,將子模塊聚合即可
這時要說一說繼承時說到的 relativePath 屬性,前面說 relativePath 屬性可以省略,前提是父模塊已經構建並 install 至倉庫,否則子模塊無法構建,但此時父模塊同時也聚合瞭子模塊,要構建父模塊就又要一起構建子模塊,但構建子模塊又需要父模塊 install 至倉庫……陷入瞭套娃問題
此時構建父模塊 maven 會報錯: Non-resolvable parent POM for XXX.XXX.XXX Could not find artifact com.mzz:parent-maven:pom:1.0-SNAPSHOT and ‘parent.relativePath’ points at wrong local POM,原因是無法定位 parent 模塊
解決方法也很簡單,要麼老老實實在子模塊中 parent 標簽中加入 relativePath 屬性,使 maven
可以根據相對路徑找到父模塊,要麼,先將父模塊中的 modules 註釋掉,暫時不做聚合,將父模塊 install 之後再取消註釋,然後就能一起構建啦
到此這篇關於Maven繼承與聚合詳解及作用介紹的文章就介紹到這瞭,更多相關Maven 繼承 聚合內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 構建Maven多模塊項目的方法
- maven多模塊項目依賴管理與依賴繼承詳解
- SpringBoot測試時卡在Resolving Maven dependencies的問題
- IDEA搭建Maven模塊化項目的實現
- Maven依賴中scope的含義