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.RELEASE的spring-beans和5.2.4.RELEASE的spring-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-context和spring-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了。