Maven直接依賴、間接依賴、依賴沖突、依賴仲裁的實(shí)現(xiàn)
直接依賴和間接依賴
在項(xiàng)目中直接引入的依賴叫做直接依賴,而那些被動引入的就叫間接依賴

比如上圖中,A 是我們的項(xiàng)目,我們在項(xiàng)目中直接引入了 B 模塊,所以 B 和 A 的關(guān)系就是直接依賴,而 B 工程內(nèi)部引入了 C,所以 B 和 C 也是直接依賴關(guān)系,如果 B 工程在引入 C 時,指定了 C 模塊的依賴范圍是 <scope>compile</scope> ,那么 C 模塊就會隨著 B 模塊一同被引入到我們的工程A 中,這時候 A 和 C 的關(guān)系就是間接依賴
依賴沖突
Maven 的依賴沖突,我認(rèn)為有兩種情況,Maven 能自動解決的、需要手動解決的
1. Maven 可以自動解決的依賴沖突
在項(xiàng)目中,不管是直接依賴還是間接依賴,當(dāng)有多個 <groupId> 、 <artifactId> 相同, <version> 不同的依賴引入時,Maven 就會認(rèn)為我們引入了相同模塊的不同版本,其就會被判定為依賴沖突,這種情況 Maven 會用自己的仲裁機(jī)制幫我們?nèi)∩?/p>
2. 需要手動解決的依賴沖突
模塊間的 <groupId> 、 <artifactId> 、 <version> 都不相同,但是引入的這些模塊中具有相同路徑的類(包名+類名完全相同),這個時候就需要我們自己去解決依賴沖突問題
Maven 的依賴仲裁
依賴仲裁是 Maven 自動解決依賴沖突的手段,我們想更好的利用它,就必須知道其仲裁的規(guī)則,其通過 最短路徑優(yōu)先 和 先聲明優(yōu)先 兩個依據(jù)來判斷最終留下的模塊
最短路徑優(yōu)先
當(dāng)項(xiàng)目的依賴樹中存在相同模塊的不同版本時,Maven 的仲裁機(jī)制就會介入,其首先會通過最短路徑的方式來對沖突的模塊進(jìn)行取舍,如下圖,假設(shè)我們的項(xiàng)目是A,明顯C模塊發(fā)生了依賴沖突,那么按照最短路徑優(yōu)先的原則,Maven 最后會留下 A → B → C 1.0 這個路徑下的 C 模塊

先聲明優(yōu)先
當(dāng)兩個依賴沖突的模塊,其路徑距離相同時,就會使用先聲明優(yōu)先的規(guī)則,這個就很簡單了,就是留下先聲明的模塊,如下圖,假設(shè)我們的項(xiàng)目是A,兩個沖突的模塊C到 A 的距離是相同的,這時 Maven 就會根據(jù)先聲明優(yōu)先的規(guī)則選擇A → B → C 1.0 這個路徑下的 C 模塊,因?yàn)槠渎暶髟谇?/p>

至于什么叫先聲明,非常簡單,用上圖例子,我寫個偽代碼
<!-- 這個 B 的依賴信息就是先聲明的,所以仲裁后會留下B模塊中依賴的C模塊 -->
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactId>
<version>release</version>
</dependency>
<dependency>
<groupId>D</groupId>
<artifactId>D</artifactId>
<version>release</version>
</dependency>了解仲裁規(guī)則后,也可以利用 Maven 的仲裁規(guī)則,保留自己想要的模塊,比如上面例子中,我們想保留模塊 C 2.0,那么就可以將模塊 C 2.0 的依賴信息主動聲明在依賴列表的最前面,這樣不論是最短路徑規(guī)則還是先聲明的規(guī)則,都會判定 C 2.0 被保留,偽代碼如下:
<!--在依賴列表的最前面主動聲明模塊C2.0的依賴信息-->
<dependency>
<groupId>C</groupId>
<artifactId>C</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactId>
<version>release</version>
</dependency>
<dependency>
<groupId>D</groupId>
<artifactId>D</artifactId>
<version>release</version>
</dependency>手動解決依賴沖突
需要手動解決的情況,是指不同模塊中,具有相同路徑的類(包名和類名完全相同),從而導(dǎo)致項(xiàng)目啟動后,類加載器加載了同名的非目標(biāo)類,從而出現(xiàn) ClassNotFoundException 、 NoClassDefFoundError 、 LinkageError 等類似的錯誤
手動解決依賴沖突,首先需要找出路徑相同的類所在的模塊,其次決定要留用的模塊
找出類路徑相同的模塊
可以借助 Maven 的生命周期插件 maven-enforcer-plugin
1. 在項(xiàng)目的 Pom.xml 中添加配置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-dependencies</id>
<phase>validate</phase>
<goals>
<goal>display-info</goal>
<goal>enforce</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>1.0-beta-4</version>
</dependency>
</dependencies>
<configuration>
<rules>
<banDuplicateClasses>
<findAllDuplicates>true</findAllDuplicates>
</banDuplicateClasses>
</rules>
</configuration>
</plugin>
</plugins>
</build>(2) 執(zhí)行 mvn clean package enforcer:enforce 命令后,就能看見重復(fù)的類和模塊

(3) 找到?jīng)_突的模塊后,刪掉棄用的模塊,如果是直接依賴的模塊直接刪除依賴信息就好,如果是間接依賴的模塊,就要使用 <exclusions> 排除依賴傳遞,方式如下:
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!-- 排除依賴傳遞 -->
<exclusions>
<exclusion>
<groupId>要棄用的模塊的groupId</groupId>
<artifactId>要棄用的模塊的artifactId</artifactId>
</exclusion>
</exclusions>
</dependency>到此這篇關(guān)于Maven直接依賴、間接依賴、依賴沖突、依賴仲裁的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Maven直接依賴、間接依賴、依賴沖突、依賴仲裁內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
完美解決idea光標(biāo)變成了insert光標(biāo)狀態(tài)的問題
這篇文章主要介紹了完美解決idea光標(biāo)變成了insert光標(biāo)狀態(tài)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
使用jekins自動構(gòu)建部署java maven項(xiàng)目的方法步驟
這篇文章主要介紹了使用jekins自動構(gòu)建部署java maven項(xiàng)目的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Java枚舉通用接口設(shè)計與實(shí)現(xiàn)方法舉例
在Java語言中枚舉(Enum)是一種特殊的數(shù)據(jù)類型,用于定義固定的常量集合,它比常量更加靈活、強(qiáng)大,這篇文章主要介紹了Java枚舉通用接口設(shè)計與實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下2025-09-09
mybatis中mapper.xml文件的常用屬性及標(biāo)簽講解
這篇文章主要介紹了mybatis中mapper.xml文件的常用屬性及標(biāo)簽講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
Spring Security實(shí)現(xiàn)登錄認(rèn)證實(shí)戰(zhàn)教程
這篇文章主要介紹了Spring Security實(shí)現(xiàn)登錄認(rèn)證實(shí)戰(zhàn)教程,本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-06-06

