Overriding Spring Boot Managed Dependency Versions – 重写Spring Boot管理的依赖性版本

最后修改: 2021年 10月 30日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

Spring Boot is an excellent framework for quickly starting new projects. One of the ways it helps developers quickly create new applications is by defining a set of dependencies suitable for most users.

Spring Boot是一个快速启动新项目的优秀框架。它帮助开发者快速创建新应用程序的方法之一是定义一套适合大多数用户的依赖关系。

However, in some cases, it may be necessary to override one or more dependency versions.

然而,在某些情况下,可能需要覆盖一个或多个依赖版本

In this tutorial, we’ll look at how to override Spring Boot managed dependencies and their versions.

在本教程中,我们将研究如何覆盖Spring Boot管理的依赖关系及其版本。

2. Spring Boot Bill of Materials (BOM)

2.Spring Boot材料清单(BOM)

Let’s start by looking at how Spring Boot manages dependencies. In short, Spring Boot uses a Bill of Materials (BOM) to define dependencies and versions.

让我们先来看看Spring Boot是如何管理依赖关系的。简而言之,Spring Boot使用材料清单(BOM)来定义依赖性和版本。

Most Spring Boot projects inherit from the spring-boot-starter-parent artifact, which itself inherits from the spring-boot-dependencies artifact. This latter artifact is the Spring Boot BOM, which is just a Maven POM file with a large dependencyManagement section:

大多数Spring Boot项目都继承自spring-boot-starter-parent artifact,它本身也继承自spring-boot-dependencies artifact。后一个工件是Spring Boot BOM,它只是一个带有大量dependencyManagement部分的Maven POM文件。

<dependencyManagement>
    <dependencies>
        <dependency>
            ...
        </dependency>
        <dependency>
            ...
        </dependency>
    </dependencies>
</dependencyManagement>

By using Maven’s dependencyManagement, the BOM can specify default library versions should our application choose to use them. Let’s look at an example.

通过使用Maven的dependencyManagement如果我们的应用程序选择使用默认的库版本,BOM可以指定这些版本。让我们看一个例子。

One of the entries in the Spring Boot BOM is as follows:

Spring Boot BOM中的一个条目如下。

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-amqp</artifactId>
    <version>${activemq.version}</version>
</dependency>

This means any artifact in the project that depends on ActiveMQ will get this version by default.

这意味着项目中任何依赖于ActiveMQ的工件都会默认获得这个版本。

Also, notice the version is specified using a property placeholder. This is a common practice in the Spring Boot BOM, and it provides the value for this and other properties inside its own properties section.

另外,注意到版本是用属性占位符指定的。这是Spring Boot BOM的常见做法,它在自己的properties部分为这个和其他属性提供了值。

3. Overriding Spring Boot Managed Dependency Versions

3.重写Spring Boot管理的依赖版本

Now that we understand how Spring Boot manages dependency versions, let’s look at we can override them.

现在我们了解了Spring Boot是如何管理依赖性版本的,让我们来看看我们可以如何覆盖它们。

3.1. Maven

3.1. Maven

For Maven, we have two options for overriding a Spring Boot managed dependency. First, for any dependency where the Spring Boot BOM specifies the version with a property placeholder, we simply need to set that property in our project POM:

对于Maven,我们有两个选择来覆盖Spring Boot管理的依赖。首先,对于Spring Boot BOM用属性占位符指定版本的任何依赖,我们只需在项目POM中设置该属性

<properties>
    <activemq.version>5.16.3</activemq.version>
</properties>

This would cause any dependency that uses the activemq.version property to use our specified version instead of the one in the Spring Boot BOM.

这将导致任何使用activemq.version属性的依赖性使用我们指定的版本而不是Spring Boot BOM中的版本。

Additionally, if the version is specified explicitly within the dependency tag in the BOM rather than as a placeholder, then we can simply override the version explicitly in our project dependency entry:

此外,如果在BOM中的dependency标签中明确指定了版本,而不是作为占位符,那么我们就可以在项目依赖项中明确覆盖version

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-amqp</artifactId>
    <version>5.16.3</version>
</dependency>

3.2. Gradle

3.2 Gradle

Gradle requires a plugin to honor dependency management from the Spring Boot BOM. Therefore, to get started, we have to include the plugin and import the BOM:

Gradle需要一个插件来实现Spring Boot BOM的依赖性管理。因此,为了开始工作,我们必须包含该插件并导入BOM。

apply plugin: "io.spring.dependency-management"
dependencyManagement {
  imports {
    mavenBom 'io.spring.platform:platform-bom:2.5.5'
  }
}

Now, if we want to override a specific version of a dependency, we just need to specify the corresponding property from the BOM as a Gradle ext property:

现在,如果我们想覆盖一个依赖的特定版本,我们只需要从BOM中指定相应的属性作为Gradle ext 属性。

ext['activemq.version'] = '5.16.3'

And if there is no property in the BOM to override, we can always specify the version directly when we declare the dependency:

如果BOM中没有要覆盖的属性,我们总是可以在声明依赖关系时直接指定版本。

compile 'org.apache.activemq:activemq-amqp:5.16.3'

3.3. Caveats

3.3.注意事项

Several caveats are worth mentioning here.

这里有几个注意事项值得一提。

For starters, it’s important to remember that Spring Boot is built and tested using the library versions specified in their BOM. Any time we specify a different library version, there is a risk we can introduce an incompatibility. Therefore it’s essential to test our applications anytime we deviate from the standard dependency versions.

首先,重要的是要记住,Spring Boot是使用其BOM中指定的库版本构建和测试的。任何时候我们指定一个不同的库版本,都有可能引入不兼容。因此,无论何时我们偏离标准依赖版本,都必须测试我们的应用程序。

Also, remember that these tips only apply when we use the Spring Boot Bill of Materials (BOM). For Maven, this means using the Spring Boot parent. And for Gradle, this means using the Spring dependencies plugin.

另外,请记住,这些提示只适用于我们使用Spring Boot物料清单(BOM)的情况。对于Maven来说,这意味着使用Spring Boot父类。对于Gradle来说,这意味着使用Spring依赖性插件。

4. Finding Dependency Versions

4.寻找依赖性版本

We’ve seen how Spring Boot manages dependency versions and how we can override them. In this section, we’ll look at how we can find the version of a library our project is using. This is useful for identifying library versions and confirming that any overrides we apply to a project are being honored. 

我们已经看到Spring Boot是如何管理依赖版本的,以及我们如何覆盖它们。在本节中,我们将看看如何找到我们的项目正在使用的库的版本。这对于识别库的版本和确认我们应用于项目的任何覆盖是否被遵守非常有用。

4.1. Maven

4.1. Maven

Maven provides a goal that we can use to display a list of all dependencies and their versions. For example, if we run the command:

Maven提供了一个目标,我们可以用它来显示所有依赖项及其版本的列表。例如,如果我们运行该命令。

mvn dependency:tree

We should see output similar to:

我们应该看到类似的输出。

[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

The output shows all artifacts and versions that are dependencies of the project. These dependencies are presented in a tree structure, making it easy to identify how every artifact is imported into the project.

输出显示了项目的所有工件和版本的依赖关系。这些依赖关系是以树状结构呈现的,使其很容易识别每个工件是如何被导入到项目的。

In the example above, the logback-classic artifact is a dependency of the spring-boot-starter-logging library, which itself is a dependency of the spring-boot-starter module. Thus, we can navigate up the tree back to our top-level project.

在上面的例子中,logback-classic工件是spring-boot-starter-logging库的一个依赖项,而后者本身是spring-boot-starter模块的一个依赖项。因此,我们可以在树上导航,回到我们的顶层项目。

4.2. Gradle

4.2 Gradle

Gradle provides a task that generates a similar dependency tree. For example, if we run the command:

Gradle提供了一个任务,可以生成一个类似的依赖树。例如,如果我们运行命令。

gradle dependencies

We will get output similar to:

我们将得到类似的输出。

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

Just like the Maven output, we can easily identify why each artifact is being pulled into the project, along with the version being used.

就像Maven的输出一样,我们可以很容易地识别每个工件被拉入项目的原因,以及使用的版本。

5. Conclusion

5.总结

In the article, we have learned how Spring Boot manages dependency versions. We also saw how to override those dependency versions in both Maven and Gradle. Finally, we saw how we could verify dependency versions in both project types.

在这篇文章中,我们已经了解了Spring Boot是如何管理依赖版本的。我们还看到了如何在Maven和Gradle中覆盖这些依赖版本。最后,我们看到了如何在两种项目类型中验证依赖版本。