问题描述
项目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 依赖的版本号