Maven依赖版本更新踩坑

问题描述

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

posted @ 2024-06-19 20:56  nuccch  阅读(16)  评论(0编辑  收藏  举报