覆盖 Spring Boot 依赖的版本号
1、简介
Spring Boot 为大多数常用的依赖、第三方库都定义好了最兼容的版本号(如 JPA、MySQL 驱动、Redis 客户端)。得益于此,我们可以快速地创建一个新应用。
但,有时出于特殊原因,我们需要修改这些预定义的依赖版本号。
2、Spring Boot 依赖清单(BOM)
Spring Boot 使用 Bill of Materials (BOM) 来定义依赖和版本。
大多数 Spring Boot 项目都继承自 spring-boot-starter-parent,而 spring-boot-starter-parent
本身又继承自 spring-boot-dependencies 。后者就是 Spring Boot BOM,它只是一个 Maven POM 文件,其中有一个很大的 ependencyManagement
节点:
<dependencyManagement>
<dependencies>
<dependency>
...
</dependency>
<dependency>
...
</dependency>
</dependencies>
</dependencyManagement>
通过使用 Maven 的 dependencyManagement
,BOM 可以指定依赖的默认版本(如果应用使用了这个依赖)。
Spring Boot BOM 中的一个依赖如下:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>${activemq.version}</version>
</dependency>
这意味着,在项目中依赖了 ActiveMQ,就会使用这个默认的版本。
另外,注意。版本是使用属性占位符指定的。这是 Spring Boot BOM 中的常见做法,它在自己的 properties
部分中提供了该属性和其他属性的值。
3、覆盖 Spring Boot 管理的依赖版本
既然已经了解了 Spring Boot 如何管理依赖版本,那就来看看如何覆盖它们。
3.1、Maven
对于 Maven,有两种方法来覆盖 Spring Boot 管理的依赖版本。首先,对于 Spring Boot BOM 通过属性占位符指定版本的任何依赖,我们只需在项目 POM 中设置该属性即可:
<properties>
<activemq.version>5.16.3</activemq.version>
</properties>
这将导致任何使用 ${activemq.version}
属性的依赖使用我们指定的版本,而不是 Spring Boot BOM 中的版本。
此外,如果版本是在 BOM 的 dependency
标签中明确指定的,而不是占位符,那么我们只需在项目 dependency
条目中明确覆盖 version
即可:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>5.16.3</version>
</dependency>
3.2、Gradle
Gradle 需要一个插件来遵循 Spring Boot BOM 的依赖管理。
包含该插件并导入 BOM:
apply plugin: "io.spring.dependency-management"
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:2.5.5'
}
}
现在,如果想覆盖某个特定依赖的版本,只需将 BOM 中的相应属性指定为 Gradle ext
属性即可:
ext['activemq.version'] = '5.16.3'
如果 BOM 中没有可覆盖的属性,可以在声明依赖时直接指定版本:
compile 'org.apache.activemq:activemq-amqp:5.16.3'
3.3、注意
Spring Boot 本身就是通过 BOM 中指定的依赖进行构建和测试的。如果你指定了不同的依赖版本,可能会导致不兼容的问题发生。因此,这种情况下你必须要对应用进行测试。
没有特殊原因,不建议覆盖 Spring Boot 依赖的默认版本号!
4、查找依赖版本
了解了 Spring Boot 如何管理依赖的版本后,再来看看如何查找项目正在使用的依赖的当前版本。
4.1、Maven
Maven 提供了一个 goal
,可以用它来显示所有依赖及其版本的列表。
例如,运行命令:
mvn dependency:tree
你可以看到类似如下的输出:
[INFO] com.baeldung:dependency-demo:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.5.7-SNAPSHOT:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.5.7-SNAPSHOT:compile
[INFO] | | +- org.springframework.boot:spring-boot:jar:2.5.7-SNAPSHOT:compile
[INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.5.7-SNAPSHOT:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.5.7-SNAPSHOT:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.6:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.6:compile
输出结果会显示项目依赖的所有工件(artifact)和版本。这些依赖关系以树形结构显示,便于识别每个依赖是如何导入到项目中的。
在上例中,logback-classic
是 spring-boot-starter-logging
的依赖,而 spring-boot-starter-logging
库本身又是 spring-boot-starter
模块的依赖。这样,我们就可以沿着树状结构追溯到顶层项目。
4.2、Gradle
Gradle 提供了一个生成类似依赖关系树的 task。
运行以下命令:
gradle dependencies
你可以看到类似于如下的输出:
compileClasspath - Compile classpath for source set 'main'.
\--- org.springframework.boot:spring-boot-starter-web -> 1.3.8.RELEASE
+--- org.springframework.boot:spring-boot-starter:1.3.8.RELEASE
| +--- org.springframework.boot:spring-boot:1.3.8.RELEASE
| | +--- org.springframework:spring-core:4.2.8.RELEASE
| | \--- org.springframework:spring-context:4.2.8.RELEASE
| | +--- org.springframework:spring-aop:4.2.8.RELEASE
和 Maven 的输出一样,可以很容易地识别出每个依赖被拉入项目的原因,以及正在使用的版本。
5、总结
本文介绍了 Spring Boot 如何管理依赖的版本,以及如何在 Maven 和 Gradle 中覆盖这些依赖的版本。
Ref:https://www.baeldung.com/spring-boot-override-dependency-versions