背景

工作中负责的一套计费系统需要开发一个新通知功能,在扣费等事件触发后发送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版本也有这个问题。完整的TestCase详见larva-zhang/some-problems-record/spring-always-assigns-default-value-to-Value-annotation

最新文章

  1. 关于DYNPRO程序的系统迁移与版本不匹配问题之一
  2. centos(x86 64位系统)使用boost
  3. NOIP欢乐模拟赛 T2 解题报告
  4. UART IP和UVM的验证平台
  5. css小技巧之去掉蓝色底块的方法
  6. phprpc 使用实例(例实没错却不能执行)函数冲突gzdecode
  7. tty &amp; pty &amp; pts
  8. cocos2d-x游戏循环与调度
  9. 动态修改log4net组件的日志文件名
  10. Python文件处理之文件读取方式(二)
  11. Nginx各个配置块功能详解
  12. 看图说话,P2P 分享率 90% 以上的 P2P-CDN 服务,来了!
  13. JavaScript 错误处理 Throw、Try 和 Catch
  14. Python学习宝典,Python400集让你成为从零基础到手写神经网络的Python大神
  15. idea使用配置
  16. leaflet.toolbar.js
  17. 信息在DNN马尔科夫链结构上的变化
  18. 如果debug调试的时候中断总是停在析构函数的delete[] p上
  19. Bootstrap-按钮相关的class
  20. sqler sql 转rest api 源码解析(二) resp 协议

热门文章

  1. MVC方法返回值数据
  2. JVM和ClassLoader
  3. shell 文件的包含
  4. 如果用了flex去加一个箭头怎么让他剧中
  5. 【转】Linux下的CPU使用率与服务器负载的关系与区别
  6. SpringMVC(十五):Dispatcher的重要组件之一MultipartResolver(StandardServletMultipartResolver和CommonsMultipartResolver)的用法
  7. ES6 - 字符串的扩展(模版字符串)
  8. Eureka Server 集群配置
  9. 大幅度改变celery日志外观,修改成日志可点击跳转和鲜艳五彩日志,解决脚本中已添加handler的logger和框架日志重复记录问题。
  10. 转 zabbix 自动发现和 zabbix自定义用户key与参数User parameters