Spring Boot Configuration Properties Migrator – Spring Boot配置属性迁移器

最后修改: 2022年 4月 16日

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

1. Introduction

1.绪论

In this tutorial, we’ll explore a support system provided by Spring to facilitate Spring Boot upgrades. In particular, we’ll be looking at the spring-boot-properties-migrator module. It helps migrate application properties.

在本教程中,我们将探讨Spring提供的一个支持系统,以促进Spring Boot的升级。特别是,我们将关注spring-boot-properties-migrator模块。它有助于迁移应用程序的属性。

With each Spring Boot version upgrade, there may be properties that are either marked as deprecated, have gone out of support, or were newly introduced. Spring publishes the comprehensive changelog for each upgrade. However, these changelogs can be a bit tedious to go through. That’s where the spring-boot-properties-migrator module comes to the rescue. It does so by providing us with personalized information for our setup.

随着每次Spring Boot版本的升级,可能会有一些属性被标记为废弃的、不再支持的或新引入的。Spring为每次升级发布了全面的变更日志。然而,这些变更日志的查阅可能有些乏味。这就是spring-boot-properties-migrator模块的作用。它通过为我们的设置提供个性化的信息来做到这一点。

Let’s see this in action!

让我们来看看这个行动吧!

2. Demo Application

2.演示应用

Let’s upgrade our Spring Boot application from version 2.3.0 to 2.6.3.

让我们把我们的Spring Boot应用程序从2.3.0版本升级到2.6.3版本。

2.1. Properties

2.1.属性

In our demo application, we have two properties files. In the default properties file, application.properties, let’s add:

在我们的演示应用程序中,我们有两个属性文件。在默认的属性文件中,application.properties,让我们添加。

spring.resources.cache.period=31536000
spring.resources.chain.compressed=false
spring.resources.chain.html-application-cache=false

For the dev profile YAML file application-dev.yaml:

对于dev配置文件YAML文件application-dev.yaml

spring:
  resources:
    cache:
      period: 31536000
    chain:
      compressed: true
      html-application-cache: true

Our properties files contain several properties that have either been replaced or removed between Spring Boot 2.3.0 and 2.6.3. Additionally, we also have both .properties and .yaml files for a better demonstration.

我们的属性文件包含了Spring Boot 2.3.0和2.6.3之间被替换或删除的几个属性。此外,我们还有.properties.yaml两个文件,以便更好地演示。

2.2. Adding the Dependency

2.2.添加依赖关系

Firstly, let’s add the spring-boot-properties-migrator as a dependency in our module:

首先,让我们把spring-boot-properties-migrator作为我们模块中的一个依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
    <scope>runtime</scope>
</dependency>

If we’re using Gradle, we can add:

如果我们使用Gradle,我们可以添加。

runtime("org.springframework.boot:spring-boot-properties-migrator")

The scope of the dependency should be runtime.

依赖关系的范围应该是runtime

3. Running the Scan

3.运行扫描

Secondly, let’s package and run our application. We’ll be using Maven to build and package:

其次,我们来打包并运行我们的应用程序。我们将使用Maven来构建和打包。

mvn clean package

Finally, let’s run it:

最后,让我们来运行它。

java -jar target/spring-boot-properties-migrator-demo-1.0-SNAPSHOT.jar

As a result, the spring-boot-properties-migrator module scans our application properties files and works its magic! More on that in a bit.

因此,spring-boot-properties-migrator模块扫描了我们的应用程序属性文件,并发挥了它的魔力!稍后会有更多关于这方面的内容。

4. Understanding the Scan Output

4.了解扫描输出

Let’s go through the logs to understand the scan’s recommendations.

让我们通过日志来了解扫描的建议。

4.1. Replaceable Properties

4.1.可替换的属性

For the properties that have a known replacement, we see WARN logs from the PropertiesMigrationListener class:

对于有已知替换的属性,我们看到WARN 来自PropertiesMigrationListener类的日志

WARN 34777 --- [           main] o.s.b.c.p.m.PropertiesMigrationListener  : 
The use of configuration keys that have been renamed was found in the environment:

Property source 'Config resource 'class path resource [application.properties]' via location 'optional:classpath:/'':
	Key: spring.resources.cache.period
		Line: 2
		Replacement: spring.web.resources.cache.period
	Key: spring.resources.chain.compressed
		Line: 3
		Replacement: spring.web.resources.chain.compressed

Property source 'Config resource 'class path resource [application-dev.yaml]' via location 'optional:classpath:/'':
	Key: spring.resources.cache.period
		Line: 5
		Replacement: spring.web.resources.cache.period
	Key: spring.resources.chain.compressed
		Line: 7
		Replacement: spring.web.resources.chain.compressed


Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.

We see all the key information in the logs, such as which property file, key, line number, and replacement key pertains to each entry. This helps us easily identify and replace all such properties. Additionally, the module replaces these properties with available replacements at runtime, allowing us to be able to run the application without having to make any changes.

我们在日志中看到所有的关键信息,例如 每个条目涉及到哪个属性文件、密钥、行号和替换密钥。这有助于我们轻松地识别和替换所有这些属性。此外,该模块在运行时将这些属性替换为可用的替换物,使我们能够运行应用程序而无需进行任何更改。

4.2. Unsupported Properties

4.2.不支持的属性

For the properties that don’t have a known replacement, we see ERROR logs from the PropertiesMigrationListener class:

对于没有已知替换的属性,我们看到ERROR 来自PropertiesMigrationListener类的日志

ERROR 34777 --- [           main] o.s.b.c.p.m.PropertiesMigrationListener  : 
The use of configuration keys that are no longer supported was found in the environment:

Property source 'Config resource 'class path resource [application.properties]' via location 'optional:classpath:/'':
	Key: spring.resources.chain.html-application-cache
		Line: 4
		Reason: none

Property source 'Config resource 'class path resource [application-dev.yaml]' via location 'optional:classpath:/'':
	Key: spring.resources.chain.html-application-cache
		Line: 8
		Reason: none

Like the previous scenario, we see the offending property file, the key, the line number in the property file, and the reason behind the key being removed. But, unlike in the previous scenario, the startup of the application may fail depending on the property in question. We might also face runtime issues since these properties couldn’t be migrated automatically.

与之前的场景一样,我们看到了违规的属性文件、密钥、属性文件中的行号,以及密钥被删除的原因。但是,与之前的场景不同,应用程序的启动可能会失败,这取决于相关的属性。由于这些属性不能自动迁移,我们还可能面临运行时的问题。

5. Updating the Configuration Properties

5.更新配置属性

Now, with the crucial information provided to us by the scan, we’re in a much better state to upgrade the properties. We know the property file to go to, the line number, and the key to either replace with the suggested replacement or consult the release notes for the specific keys that have no replacement.

现在,有了扫描提供给我们的关键信息,我们就可以更好地升级属性了。我们知道要去的属性文件、行号,以及要用建议的替代物替换的键,或者查阅发行说明中没有替代物的特定键。

Let’s fix our properties files. In the default properties file, application.properties, let’s replace the properties as per the recommendation:

让我们来修复我们的属性文件。在默认的属性文件中,application.properties,让我们按照建议替换属性。

spring.web.resources.cache.period=31536000
spring.web.resources.chain.compressed=false

Similarly, let’s update the dev profile YAML file application-dev.yaml:

同样地,让我们更新dev配置文件YAML文件application-dev.yaml

spring:
  web:
    resources:
      cache:
        period: 31536000
      chain:
        compressed: false

To summarize, we’ve replaced the properties spring.resources.cache.period with spring.web.resources.cache.period and spring.resources.chain.compressed with spring.web.resources.chain.compressed. The spring.resources.chain.html-application-cache key is no longer supported in the new version. Hence, we’ve removed it in this case.

总的来说,我们用spring.web.resources.cache.period替换了属性spring.resources.cache.period,用spring.web.resources.chain.compressed替换了spring.web.resources.chain.compressed>。spring.resources.chain.html-application-cache键在新版本中不再被支持。因此,在这种情况下,我们已经删除了它。

Let’s once again run the scan. First, let’s build the application:

让我们再一次运行扫描。首先,让我们构建应用程序。

mvn clean package

Then, let’s run it:

然后,让我们来运行它。

java -jar target/spring-boot-properties-migrator-demo-1.0-SNAPSHOT.jar

Now, all the information logs we saw earlier from the PropertiesMigrationListener class disappear, indicating that our properties migration is successful!

现在,我们之前从PropertiesMigrationListener类中看到的所有信息日志都消失了,这表明我们的属性迁移已经成功了!我们可以看到,所有的信息日志都被删除了。

6. How Does All This Work? A Peek Under the Hood

6.这一切是如何运作的?窥视一下引擎盖下的情况

A Spring Boot Module JAR contains a spring-configuration-metadata.json file in the META-INF folder. These JSON files are the sources of the information for the spring-boot-properties-migrator module. When it scans our properties files, it pulls the relevant properties’ metadata information from these JSON files to build the scan report.

Spring Boot模块JAR包含spring-configuration-metadata.json文件,该文件位于META-INF文件夹中。这些JSON文件是spring-boot-properties-migrator模块的信息来源。当它扫描我们的属性文件时,它会从这些JSON文件中提取相关属性的元数据信息来建立扫描报告。

An example from the file shows the various information that we see in the generated reports:

文件中的一个例子显示了我们在生成的报告中看到的各种信息。

In spring-autoconfigure:2.6.3.jarMETA-INF/spring-configuration-metadata.json, we’ll find the entry for spring.resources.cache.period:

spring-autoconfigure:2.6.3.jarMETA-INF/spring-configuration-metadata.json中,我们会发现spring.resources.cache.period的条目。

{
    "name": "spring.resources.cache.period",
    "type": "java.time.Duration",
    "deprecated": true,
    "deprecation": {
        "level": "error",
        "replacement": "spring.web.resources.cache.period"
    }
}

Similarly, in spring-boot:2.0.0.RELEASE.jar META-INF/spring-configuration-metadata.json, we’ll find the entry for banner.image.location:

同样,在spring-boot:2.0.0.RELEASE.jar META-INF/spring-configuration-metadata.json中,我们将找到banner.image.location的条目。

{
    "defaultValue": "banner.gif",
    "deprecated": true,
    "name": "banner.image.location",
    "description": "Banner image file location (jpg\/png can also be used).",
    "type": "org.springframework.core.io.Resource",
    "deprecation": {
        "level": "error",
        "replacement": "spring.banner.image.location"
    }
}

7. Caveats

7.注意事项

Before we wrap this article, let’s go over some of the caveats with the spring-boot-properties-migrator.

在我们总结这篇文章之前,让我们回顾一下spring-boot-properties-migrator的一些注意点。

7.1. Don’t Keep This Dependency in Production

7.1.不要在生产中保留这种依赖关系

This module is meant to be used only during the upgrades in development environments. Once we identify the properties to be updated or removed and then correct them, we can remove the module from our dependencies. Eventually, we should never include this module in higher environments. It’s not recommended due to certain costs associated with it.

这个模块只在开发环境下的升级过程中使用。一旦我们确定了需要更新或删除的属性,然后对其进行修正,我们就可以将该模块从我们的依赖关系中删除。最终,我们不应该在更高的环境中包含这个模块。这是不推荐,因为与之相关的某些费用。

7.2. Historical Properties

7.2.历史属性

We shouldn’t jump the versions during upgrades because the module may not be able to detect the really old properties deprecated in the much older versions. For example, let’s add banner.image.location to our application.properties file:

在升级过程中,我们不应该跳过版本,因为模块可能无法检测到在更早的版本中被废弃的真正的旧属性。例如,让我们把banner.image.location添加到我们的application.properties文件:

banner.image.location="myBanner.txt"

This property was deprecated in Spring Boot 2.0. If we try to run our application with Spring Boot version 2.6.3 directly, we won’t see any warning or error message regarding it. We’d have to run the scan with Spring Boot 2.0 to be able to detect this property:

这个属性在Spring Boot 2.0中被淘汰了。如果我们尝试用Spring Boot 2.6.3版本直接运行我们的应用程序,我们不会看到任何关于它的警告或错误信息。我们必须用Spring Boot 2.0运行扫描,才能够检测到这个属性。

WARN 25015 --- [           main] o.s.b.c.p.m.PropertiesMigrationListener  : 
The use of configuration keys that have been renamed was found in the environment:

Property source 'applicationConfig: [classpath:/application.properties]':
    Key: banner.image.location
	Line: 5
	Replacement: spring.banner.image.location


Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.

8. Conclusion

8.结语

In this article, we explored the spring-boot-properties-migrator. It’s a handy tool that scans our properties file and gives easily actionable scan reports. We also looked at the high-level view of how the module achieves its feat. Finally, to ensure this tool’s best utilization, we went over a few caveats.

在这篇文章中,我们探讨了spring-boot-properties-migrator。它是一个方便的工具,可以扫描我们的属性文件并给出容易操作的扫描报告。我们还看了该模块如何实现其壮举的高层视图。最后,为了确保这个工具的最佳利用,我们看了一些注意事项。

As always, the code is available over on GitHub.

一如既往,代码可在GitHub上获得over。