問題描述
專案xx基於Spring Boot框架,其<parent>
配置如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath />
</parent>
在spring-boot-dependencies-2.4.2.pom
中透過<dependencyManagement>
配置的caffine版本為2.8.8
。
<properties>
<caffeine.version>2.8.8</caffeine.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
專案yy是一個基礎的Maven模組,在其pom.xml
中新增了3.1.8
版本的caffeine配置。
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
此時在xx專案中新增對yy模組的依賴,即:
<dependency>
<groupId>x.y.z</groupId>
<artifactId>yy</artifactId>
<version>1.0</version>
</dependency>
至此,重新梳理下xx,yy,Spring Boot以及caffeine的依賴關係如下:
如上圖,按照對Maven傳遞依賴的理解,此時在xx專案中使用的caffeine
版本應該是在yy專案中配置的3.1.8
,但實際結果卻是使用的spring-boot-dependencies-2.4.2.pom
中定義的2.8.8
。
這顯示不是我們期望的結果!
解決辦法
經過實驗發現,凡是在<parent>
中透過<dependencyManagement>
管理的元件版本優先順序都比向下依賴的元件版本優先順序高。
那麼當我們需要修改元件版本以覆蓋在<parent>
定義的元件版本時,該怎麼實現呢?根據不同的情況有2種辦法。
版本定義覆蓋
這種解決辦法適用於:
1.專案的<parent>
直接設定為透過<dependencyManagement>
管理元件的模組
2.在<parent>
中透過<properties>
定義了元件版本
示例:
在spring-boot-dependencies-2.4.2.pom
中透過<dependencyManagement>
配置的caffine版本為2.8.8
。
<properties>
<caffeine.version>2.8.8</caffeine.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
將xx
專案的<parent>
設定為spring-boot-starter-parent
:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath />
</parent>
<properties>
<caffeine.version>3.1.8</caffeine.version>
</properties>
在xx
的<properties>
重新定義<caffeine.version>
為新版本號,如:3.1.8
,此時將會使用在xx
中定義的<caffeine.version>
(3.1.8
)覆蓋在spring-boot-dependencies-2.4.2.pom
中定義的<caffeine.version>
(2.8.8
),也就達到了更新元件版本的目的。
重新依賴元件
倘若專案的<parent>
不是直接設定為透過<dependencyManagement>
管理元件的模組,或者在<parent>
中沒有透過<properties>
定義元件版本,那麼此時就只能在專案中重新依賴元件及版本了,這樣也能達到覆蓋在<parent>
中定義的元件版本的目的。
場景1:專案的<parent
>不是直接設定為透過<dependencyManagement>
管理元件的模組
<!-- 沒有直接將Spring Boot設定為parent -->
<parent>
<artifactId>test-java-samples</artifactId>
<groupId>org.chench.extra</groupId>
<version>1.0</version>
</parent>
<!-- Spring Boot透過dependencyManagement引入 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
場景2:在<parent>
中未透過<properties>
中定義了元件版本
<!-- 在parent中未定義版本property -->
<!-- 自然也就無法透過重新定義property來達到覆蓋版本的目的 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.8</version>
</dependency>
</dependencies>
</dependencyManagement>
在xx
專案中重新依賴元件,以達到版本更新的目的。
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
使用該方式解決的版本更新問題,依靠的是版本優先順序的機制。
完畢!
【參考】
記錄一次Maven依賴傳遞,模組之間依賴版本不一致問題
覆蓋 Spring Boot 依賴的版本號