应用中有多个Spring Property PlaceHolder导致@Value只能获取到默认值
Posted larva-zhh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用中有多个Spring Property PlaceHolder导致@Value只能获取到默认值相关的知识,希望对你有一定的参考价值。
背景
工作中负责的一套计费系统需要开发一个新通知功能,在扣费等事件触发后发送MQ,然后消费MQ发送邮件或短信通知给客户。因为有多套环境,测试时需要知道是从哪套环境发出的邮件,又不想维护多套通知模板,因此就打算在各环境的properties中声明不同的title前缀,实现类似[DEV]您的xx月账单
、[TEST]您的xx月账单
的效果,但是这个前缀需要在生产环境中去掉,因此我想到用Spring @Value
的默认值来实现,伪代码如下:
@Value("$notice.mail.titlePrefix:")
private String mailTitlePrefix;
public void doSendEmail()
...
String title = "xxx";
if (StringUtils.isNotBlank(mailTitlePrefix))
title = mailTitlePrefix + title;
mailSender.send(title, content, recevier);
采用上述代码后,运行发现,即使在properties中配置了值,但是mailTitlePrefix
一直是空字符串""
,一旦把冒号去掉又能正常读取到配置的值,修改:
后面的数据为其他值,如@Value("$notice.mail.titlePrefix:113")
,mailTitlePrefix
的值也为113
,即@Value
一直只能获取到默认值。
工程采用spring标签声明了两个property-placeholder
,分别读取不同的配置文件:
<context:property-placeholder order="0" location="classpath*:db.properties" ignore-unresolvable="true"/>
<context:property-placeholder order="0" location="classpath*:config.properties" ignore-unresolvable="true"/>
notice.mail.titlePrefix
的配置在config.properties
文件中。
问题定位
可以确定是spring属性值注入出现的问题,google一番后,找到一篇相同问题的文章spring-boot-spring-always-assigns-default-value-to-property-despite-of-it-bein。
按照 SPR-9989 上的说明,Spring在有多个property-placeholder
时,如果第一个property-placeholder
在处理@Value
时没有找到属性值,则会采用默认值对属性进行赋值,然后第二个property-placeholder
就会忽略该@Value
,于是@Value
获取到的永远都是默认值。
问题解决
合并property-placeholder
声明:
<context:property-placeholder order="0" location="classpath*:db.properties,classpath*:config.properties" ignore-unresolvable="true"/>
追加
这个bug一直是未修复状态,好像Spring官方不认为这是一个bug?截至spring 5.2.x
版本也有这个问题。
以上是关于应用中有多个Spring Property PlaceHolder导致@Value只能获取到默认值的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 应用程序未连接到 Mongodb 的 application.property 中指定的数据库
带有 Docker 的 Spring Boot 2.3。当我在同一个存储库中有多个 Spring Boot 应用程序时,我想为特定应用程序构建映像
spring boot中的底层配置文件application.yam(application.property)的装配原理初探
是否可以在 Spring 应用程序上下文中配置 OpenSessionInViewFilter 以便 context:property-placeholder 可用?