應用中有多個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版本也有這個問題。完整的TestCase詳見larva-zhang/some-problems-record/spring-always-assigns-default-value-to-Value-annotation


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM