【maven】jar包版本衝突解決的三種方式

pom.xml 添加一個spring-context的jar包

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.4.RELEASE</version>
</dependency>

在左邊External Libraibraries看到依賴了好幾個包

右邊Maven視窗打開依賴圖[Show Dependencies] 

此時,在pom.xml 再添加一個spring-beans的jar包,注意版本是4.2.4.RELEASE

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

此時發現External Libraibraries顯示的依賴包中spring-beans的版本發生了變化,但spring-beans所依賴的另一個spring-core的版本卻沒有發生變化。

再打開依賴圖[Show Dependencies] ,發現此時的兩個同樣的jar包spring-beans版本是有衝突的,而且兩個spring-beans所依賴的spring-core包版本也不同。我們發現maven最後選擇的是4.2.4.RELEASEspring-beans5.2.4.RELEASEspring-core。那maven到底是如何來解決jar包版本衝突問題的呢?


maven工程要導入jar包的座標,就必須要考慮解決jar包版本衝突的問題。 主要有三種解決方式。

#1->第一聲明優先原則

pom.xml文件按從上至下的順序,哪個jar包的座標在上面,這個jar包就是先聲明的。先聲明的jar包座標下的依賴jar包,可以優先進入項目中。

例如,現在的pom.xml中關於spring-beans和spring-context順序是這樣的。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

spring-context先聲明,spring-beans後聲明,因此它們共同依賴的spring-core包最終選擇的是和spring-context版本保持一致的5.2.4.RELEASE。

現在如果將spring-context和spring-beans的聲明順序調換一下

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
    
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.4.RELEASE</version>
</dependency>

這裏的spring-core版本就變成和spring-beans保持一致的4.2.4.RELEASE了。

 


關於maven導入jar包的兩個概念

[直接依賴] 項目中直接導入的jar包,就是該項目的直接依賴包。

[傳遞依賴] 項目中沒有直接導入的jar包,可以通過項目直接依賴的jar包傳遞到項目中去。

例如這個項目中直接依賴spring-contextspring-beans兩個jar包,這兩個jar包所依賴的spring-core就屬於傳遞依賴包。


 

 #2->路徑近者優先原則 

直接依賴路徑比傳遞依賴路徑近,那麼最終項目進入的jar包是路徑更近的直接依賴包。

例如,此時pom.xml再添加一個5.1.0.RELEASE的spring-core

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.1.0.RELEASE</version>
</dependency>

-> spring-context 5.2.4.RELEASE 會依賴一個 spring-core 5.2.4.RELEASE [傳遞依賴路徑]

-> spring-beans 4.2.4.RELEASE 會依賴一個 spring-core 4.2.4.RELEASE [傳遞依賴路徑]

-> spring-core 5.1.0.RELEASE [直接依賴路徑]

所以最終[直接依賴路徑]的 spring-core 5.1.0.RELEASE 成功進入了項目中,幹掉了上面兩個傳遞依賴路徑進來的jar包。

 

 #3->直接排除法(推薦方法)

當需要排除某個jar包下的依賴包,如這裏想排除掉spring-beans 4.2.4.RELEASE所依賴的spring-core 4.2.4.RELEASE時,可以通過配置<exclusion></exclusion>標籤,將不需要的jar包排除掉。

注意標籤內部不需要寫明版本號,原因是這裏的依賴包默認版本和直接依賴包的版本是保持一致的,意思就是說,這裏所依賴的spring-core的版本只可能是4.2.4.RELEASE,沒有其他可能。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.4.RELEASE</version>
</dependency>

按照聲明第一的原則,spring-core的版本應該會和優先聲明的spring-beans的版本保持一致,但添加<exclusion></exclusion>標籤將這一版本中的spring-core排除掉之後,最終引入項目的就是spring-context中所依賴的spring-core了。

學習資料來源:https://www.bilibili.com/video/av70969191?p=30

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章