问题描述
是否有推荐的方法将重组/重命名引入外部化配置,同时为仍然依赖旧配置结构的消费者保持向后兼容性?
例如,假设一个库使用了过去通过 @ConfigurationProperties
定义的以下配置结构:
old-properties:
an:
old-property: true
another:
custom-property: 1234
该库的新版本将配置重新定义为如下所示:
my-library:
a-property: true
another-property: 1234
有没有好的方法可以在一段时间内保持对现有消费者的兼容性的同时弃用旧结构?使用新版本库的消费者应该仍然可以使用 old-properties.an.old-property
并将其自动映射到 my-library.a-property
。
我知道使用 additional configuration metadata 将属性标记为已弃用的功能,但我正在明确寻找一种方法来支持这两个版本以简化迁移。
解决方法
Spring Boot 配置处理器为此提供了一个 @DeprecatedConfigurationProperty
注释。生成的元数据文件将包含任何原因/替换说明,如果使用带注释的属性,这会导致记录适当的弃用警告。
请参阅 here 了解基本示例,或参阅 CassandraProperties.java 了解实际用例。
要为未映射到 @ConfigurationProperties
bean 的属性实现相同的行为,您可以在 META-INF/additional-spring-configuration-metadata.json
中手动指定它们(请参阅 Spring Boot docs 以供参考,以及示例 here) .
我研究了 Spring Boot 如何处理 deprecation phase for logging.file
(已被 logging.file.name
替换),当他们直接在代码中实现回退时,我决定通过创建新的 {{1} } 在 @ConfigurationProperties
方法中,该方法处理从旧属性名称设置值(如果可用)。
鉴于新的配置结构如下所示(为简洁起见,使用 Lombok):
@Bean
import lombok.Data;
@Data
public class MyLibraryConfigurationProperties {
private String aProperty;
private String anotherProperty;
}
方法现在负责读取旧值并将其应用于属性:
@Bean
如果新值也是通过配置设置的,它将覆盖从旧属性设置的值。