Spring5中@Value已加载properties属性却仍解析为默认值问题
问题原因
这个问题是Spring 5环境下占位符解析的常见问题,核心原因集中在两类场景:
1. Spring 5.0.x早期版本的已知Bug
Spring 5.0.0~5.0.4版本存在官方记录的占位符解析缺陷:当带默认值的${key:default}占位符解析时,会跳过@PropertySource加载的自定义属性源,直接返回冒号后的默认值,不带默认值的占位符解析不受影响。
2. 容器中存在多个冲突的占位符处理器
如果Spring版本高于5.0.4,那基本是占位符处理器配置冲突导致:
@PropertySource加载的配置会存入Spring上下文的Environment属性源集合,只有Spring 3.1+推出的PropertySourcesPlaceholderConfigurer处理器支持读取Environment中的属性源,同时兼容${key:default}的默认值语法。- 如果你项目中显式配置了旧版的
PropertyPlaceholderConfigurerBean,或者多个优先级不同的PropertySourcesPlaceholderConfigurer实例,且优先级更高的处理器:- 无法读取
@PropertySource加载的属性源 - 同时配置了
ignoreUnresolvablePlaceholders = true
就会出现以下解析逻辑:
- 不带默认值的
${com.demo.app.authEnabled}:优先级高的处理器找不到对应配置,直接返回原占位符给后续处理器,后续支持Environment的处理器可以正常找到属性值返回true。 - 带默认值的
${com.demo.app.authEnabled:false}:旧版处理器不识别冒号默认值语法,会把完整字符串com.demo.app.authEnabled:false作为key查找,找不到就返回原占位符;或者部分配置错误的新版处理器会直接匹配到默认值直接返回false,不再向后传递解析。
- 无法读取
解决方案
按优先级依次排查即可解决:
- 如果你使用的是5.0.4及以下版本的Spring,直接升级到Spring 5.0.5+或更高的稳定版本(推荐5.3.x长期支持版本)即可修复官方Bug。
- 检查容器中所有占位符处理器的配置,删除旧版
PropertyPlaceholderConfigurer的显式配置,统一使用PropertySourcesPlaceholderConfigurer。 - 纯注解场景下,确保在配置类中显式声明静态的
PropertySourcesPlaceholderConfigurerBean(必须用static修饰保证提前初始化):
@Configuration @PropertySource({ "classpath:/config.properties"}) public class ConfigBean { @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } }
- 如果确实需要配置多个占位符处理器,需将优先级最高的处理器的
ignoreUnresolvablePlaceholders属性设为true,保证解析失败的占位符可以传递给后续处理器处理。
内容的提问来源于stack exchange,提问作者Pakk
相关产品推荐
相关产品推荐

