应用中有多个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版本也有这个问题。

原文地址:https://www.cnblogs.com/larva-zhh/p/11395844.html

时间: 2024-11-17 10:20:18

应用中有多个Spring Property PlaceHolder导致@Value只能获取到默认值的相关文章

spring in action 学习十一:property placeholder Xml方式实现避免注入外部属性硬代码化

这里用到了placeholder特有的一个语言或者将表达形式:${},spring in action 描述如下: In spring wiring ,placeholder values are property names wrapped with ${...},as an exampl,you can resolve the constructor arguments for a BlankDisc in xml like this : <bean id="sgtPeppers&qu

spring @Value 设置默认值

@Value 的作用不用说 大家都知道 注解模式下 读取配置文件 注入属性值 /** * MQ地址 */ @Value("${NamesrvAddr}") private String namesrvAddr;   上面的是一个标着的 @Value 注解 如果配置文件中没有设置 NamesrvAddr Spring 在启动的时候讲报错. 设置默认值很简单 @Value("${NamesrvAddr:192.168.0.1}") private String name

Spring core resourc层结构体系及JDK与Spring对classpath中资源的获取方式及结果对比

1. Spring core resourc层结构体系 1.1. Resource相关结构体系 1.2. ResourceLoader相关体系 2. JDK与Spring对classpath中资源的获取方式及结果对比

ssas 为绑定指定的大小太小,导致一个或多个列值被截断

错误信息:ssas 为绑定指定的大小太小,导致一个或多个列值被截断 如果更改了某个维度或是事实表的字段长度,在处理CUBE时提示此错误,我们要做以下更新: 1.刷新数据源视图. 2.打开多维数据集,查看代码,去修改相关字段的DataSize. 3.如果是维度,还要打开维度,去修改相关字段的DataSize.

spring mvc 绑定参数据默认值,是否必传,(RequestParam(value=&quot;id&quot;,defaultValue=&quot;1&quot;,required=true) )

@RequestMapping(value = "/detail", method = RequestMethod.GET) public String newDetail(@RequestParam(value="id",defaultValue="1",required=true) int id,@RequestParam(value="typeId",defaultValue="2",required

Spring Boot通过application.yml配置文件获取属性及类信息

实体类信息Spring Boot通过application.yml配置文件获取属性及类信息 原文地址:https://blog.51cto.com/6000734/2354529

spring in action 学习十二:property placeholder 注解的方式实现避免注入外部属性硬代码化

这里的注解是指@PropertySource这个注解.用@PropertySource这个注解加载.properties文件. 案例的目录结构如下: student.properties的代码如下: 1 #用配置文件的形式,避免注入属性值的硬代码化. 2 name=AbrahamLincoln 3 age=21 Student的代码如下: 1 package com.advancedWiring.ambiguityIniAutowiring2; 2 3 import org.springfram

[Spring] - Property注入

使用Spring注入Properies文件方法: 1.src中新建一个settings.properties文件,内容如下: db_driverClassName=com.mysql.jdbc.Driver db_url=jdbc:mysql://127.0.0.1/test db_username=root db_password=root test_userName=Robin test_age=18 2.在spring的applicationContext.xml中加入这段: <bean

spring property扩展

复制代码 package com.sf.integration.ident.redis; import java.io.IOException; import java.util.Properties; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; public class SSSPropertyPlaceholderConfigurer extends PropertyPlaceho