Spring Boot 属性迁移

1、简介

本文将带你了解 spring-boot-properties-migrator 模块,它是 Spring 为促进 Spring Boot 升级而提供的支持。用于帮助迁移 application properties。

随着每个 Spring Boot 版本的升级,可能会有一些属性被标记为已弃用、不再支持或新引入的属性。Spring 为每个升级发布了详细的 变更日志。然而,阅读这些变更日志可能会有些繁琐。这就该 spring-boot-properties-migrator 出场了,它通过为我们的设置提供个性化的信息来帮助我们进行属性迁移。

让我们来看看如何使用。

2、Demo 应用

把 Spring Boot 应用从 2.3.0 升级到 2.6.3

2.1、Properties

在演示应用中,有两个 properties 文件。在默认 properties 文件 application.properties 中,添加如下配置:

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

dev Profile YAML 文件 application-dev.yaml

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

properties 文件包含了几个在 Spring Boot 2.3.0 和 2.6.3 之间被替换或移除的属性。

同时提供了 .properties.yaml 文件,以便更好地进行演示。

2.2、添加依赖

添加 spring-boot-properties-migrator 模块。

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

如果使用的是 Gradle:

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

依赖的 scope,应该是 runtime

3、运行扫描

接着,使用 Maven 来打包应用:

mvn clean package

最后,运行:

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

spring-boot-properties-migrator 模块会扫描我们的 application properties 文件并生成报告!

4、理解扫描的输出

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

4.1、可替换的属性

对于已知替换的属性,可以从 PropertiesMigrationListener 类中看到 WARN 日志:

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.

可以看到日志中的所有关键信息,如每个条目对应的属性文件、key、行号和替换 key。这有助于我们轻松识别和替换所有此类属性。此外,该模块还能在运行时用可用的替换属性替换这些属性,使我们无需做任何更改就能运行应用程序。

4.2、不支持的属性

对于没有已知替换的属性,可以从 PropertiesMigrationListener 类中看到 ERROR 日志:

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

与前一种情况一样,我们可以看到 “非法” 的属性文件、key、属性文件中的行号以及 key 被删除的原因。但是,与前面的场景不同,应用的启动可能会失败,这取决于具体的属性。我们还可能面临运行时问题,因为这些属性无法自动迁移。

5、更新配置属性

现在,通过扫描提供给我们的关键信息,升级属性就更好操作了。我们知道要修改属性文件、行号以及要替换的 key,可以将其替换为建议的替代项,或者查阅发行说明以获取没有替代项的特定 key 的信息。

修改 properties 文件。在默认 properties 文件 application.properties 中,按照建议替换属性:

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

同样,更新 dev profile YAML 文件 application-dev.yaml

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

总而言之,用 spring.web.resources.cache.period 替换了 spring.resources.cache.period 属性,并用 spring.web.resources.chain.compressed 替换了 spring.resources.chain.compressed 属性。新版本不再支持 spring.resources.chain.html-application-cache 属性。因此,在本例中删除了它。

再次运行扫描。

首先,构建应用:

mvn clean package

然后,再次运行:

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

现在,之前从 PropertiesMigrationListener 类中看到的所有信息日志都消失了,这表明属性迁移成功了!

6、实现原理

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

示例如下。

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"
    }
}

同样,在 spring-boot:2.0.0.RELEASE.jarMETA-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、注意事项

在本文结束前,再了解一些 spring-boot-properties-migrator 的注意事项。

7.1、不要在生产环境中保留这个依赖

该模块仅用于 开发 环境中的升级。一旦确定了需要更新或移除的属性并进行了修正,就可以从依赖中移除该模块。不应该 在其他环境中使用该模块,因为会产生一定的性能消耗。

7.2、历史属性

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

banner.image.location="myBanner.txt"

该属性 在 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、总结

本文介绍了如何通过 spring-boot-properties-migrator 工具来扫描 properties 文件并生成扫描报告来帮助我们升级属性配置,以及它的运行原理和一些注意事项。


参考:https://www.baeldung.com/spring-boot-properties-migrator