Spring Boot如何读取首字母不同的同名配置属性?
Spring Boot无法区分首字母大小写不同的配置项问题解决
场景说明
在Spring Boot应用中导入了datamart.yaml配置文件,主配置文件内容:
spring: config: import: datamart.yaml
datamart.yaml中存在两个仅首字母大小写不同的配置节点:
datamarts: Test: streamname: test header: test priority: 1 action: upload test: streamname: test.delete header: test priority: 111 action: delete
问题现象
使用@ConfigurationProperties配置类绑定配置时,Spring默认忽略大小写,把Test和test视为同一个配置键,最终只会读取最后一个test的配置内容。最初的配置类代码:
@Data @Component @AllArgsConstructor @NoArgsConstructor @ConfigurationProperties(prefix = "datamarts", ignoreUnknownFields = false) public class DatamartProperties { private DatamartType test = new DatamartType(); @Data @AllArgsConstructor @NoArgsConstructor public static class DatamartType { private String streamname; private String header; private int priority; private String action; } }
当前手动可行方案
目前通过Environment手动读取配置可以区分大小写,但代码繁琐。当前实现:
@Data @Component public class DatamartProperties { private final ApplicationContext applicationContext; private final DatamartType test; private final DatamartType testDelete; public DatamartProperties(ApplicationContext applicationContext) { this.applicationContext = applicationContext; this.test = new DatamartType( applicationContext.getEnvironment().getProperty("datamarts.Test.streamname", String.class), applicationContext.getEnvironment().getProperty("datamarts.Test.header", String.class), applicationContext.getEnvironment().getProperty("datamarts.Test.priority", Integer.class), applicationContext.getEnvironment().getProperty("datamarts.Test.action", String.class) ); this.testDelete = new DatamartType( applicationContext.getEnvironment().getProperty("datamarts.test.streamname", String.class), applicationContext.getEnvironment().getProperty("datamarts.test.header", String.class), applicationContext.getEnvironment().getProperty("datamarts.test.priority", Integer.class), applicationContext.getEnvironment().getProperty("datamarts.test.action", String.class) ); }
更简便的Spring自动配置方案
1. 为配置类开启大小写敏感绑定
Spring Boot 2.2+版本开始,@ConfigurationProperties注解支持caseSensitive属性,设置为true即可开启严格大小写匹配。修改配置类如下:
@Data @Component @AllArgsConstructor @NoArgsConstructor @ConfigurationProperties(prefix = "datamarts", ignoreUnknownFields = false, caseSensitive = true) public class DatamartProperties { // 字段名与配置节点名完全一致(包括大小写) private DatamartType Test; private DatamartType test; @Data @AllArgsConstructor @NoArgsConstructor public static class DatamartType { private String streamname; private String header; private int priority; private String action; } }
这样Spring会严格区分Test和test两个配置节点,分别绑定到对应的字段上。
2. 使用Map批量接收配置(推荐多节点场景)
如果有多个类似的大小写不同的配置节点,用Map接收更灵活,同样开启大小写敏感:
@Data @Component @ConfigurationProperties(prefix = "datamarts", caseSensitive = true) public class DatamartProperties { // 配置节点名作为Map的key,自动绑定对应的值到DatamartType private Map<String, DatamartType> datamarts; @Data @AllArgsConstructor @NoArgsConstructor public static class DatamartType { private String streamname; private String header; private int priority; private String action; } }
使用时直接通过key获取对应配置:
// 获取Test节点配置 DatamartType testUpload = datamartProperties.getDatamarts().get("Test"); // 获取test节点配置 DatamartType testDelete = datamartProperties.getDatamarts().get("test");
3. 全局开启配置大小写敏感(谨慎使用)
如果需要全局所有配置都严格区分大小写,可以在配置文件中添加:
spring: config: case-sensitive: true
该配置从Spring Boot 2.4+开始支持,会影响所有配置文件的键匹配,需确认不会影响其他配置的绑定。
内容的提问来源于stack exchange,提问作者Efrem Zapryagaev
相关产品推荐
相关产品推荐

