1、简介 {#1简介}
本文将带你了解 spring-boot-properties-migrator
模块,它是 Spring 为促进 Spring Boot 升级而提供的支持。用于帮助迁移 application properties。
随着每个 Spring Boot 版本的升级,可能会有一些属性被标记为已弃用、不再支持或新引入的属性。Spring 为每个升级发布了详细的 变更日志。然而,阅读这些变更日志可能会有些繁琐。这就该 spring-boot-properties-migrator
出场了,它通过为我们的设置提供个性化的信息来帮助我们进行属性迁移。
让我们来看看如何使用。
2、Demo 应用 {#2demo-应用}
把 Spring Boot 应用从 2.3.0 升级到 2.6.3。
2.1、Properties {#21properties}
在演示应用中,有两个 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、添加依赖 {#22添加依赖}
添加 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、运行扫描 {#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理解扫描的输出}
通过日志来了解扫描的建议。
4.1、可替换的属性 {#41可替换的属性}
对于已知替换的属性,可以从 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、不支持的属性 {#42不支持的属性}
对于没有已知替换的属性,可以从 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、更新配置属性 {#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、实现原理 {#6实现原理}
Spring Boot 模块 JAR 的 META-INF
文件夹中包含一个 spring-configuration-metadata.json
文件。这些 JSON 文件是 spring-boot-properties-migrator
模块的信息来源。当模块扫描我们的 properties 文件时,它会从这些 JSON 文件中提取相关属性的元数据信息,从而生成扫描报告。
示例如下。
在 spring-autoconfigure:2.6.3.jar
的 META-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.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、注意事项 {#7注意事项}
在本文结束前,再了解一些 spring-boot-properties-migrator
的注意事项。
7.1、不要在生产环境中保留这个依赖 {#71不要在生产环境中保留这个依赖}
该模块仅用于 开发 环境中的升级。一旦确定了需要更新或移除的属性并进行了修正,就可以从依赖中移除该模块。不应该 在其他环境中使用该模块,因为会产生一定的性能消耗。
7.2、历史属性 {#72历史属性}
在升级过程中,不应该跳版本,因为模块可能无法检测到旧版本中已废弃的旧属性。例如,在 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、总结 {#8总结}
本文介绍了如何通过 spring-boot-properties-migrator
工具来扫描 properties 文件并生成扫描报告来帮助我们升级属性配置,以及它的运行原理和一些注意事项。
参考:https://www.baeldung.com/spring-boot-properties-migrator