關(guān)于spring屬性占位符用法
在bean定義時(shí)設(shè)置bean屬性的值時(shí),除了設(shè)置固定的值,還可以通過(guò)EL表達(dá)式和占位符來(lái)設(shè)置,容器在解析bean定義時(shí)會(huì)對(duì)EL表達(dá)式和占位符進(jìn)行解析求值。
本篇來(lái)學(xué)習(xí)一下通過(guò)占位符定義屬性的用法。
占位符的取值范圍有三個(gè):
- 系統(tǒng)變量(System.getProperty)
- 壞境變量(System.getEnv)
- 自定義的Properties文件
Spring提供了三種方式來(lái)配置加載自定義的properties:
1、PropertyPlaceholderConfigurer
一個(gè)BFPP,通過(guò)location屬性把properties文件的路徑傳入,并且可以設(shè)置系統(tǒng)變量加載模式,有三種:
- 不檢查系統(tǒng)屬性;
- 優(yōu)先加載自定義屬性,加載不到時(shí)加載系統(tǒng)屬性;
- 優(yōu)先加載系統(tǒng)屬性,加載不到時(shí)再加載自定義屬性。通過(guò)systemPropertiesMode設(shè)置加載模式。占位符的前后綴默認(rèn)是${和},但是可以通過(guò)設(shè)置placeholderPrefix和placeholderSuffix來(lái)修改前后綴。
PropertyPlaceholderConfigurer的用法如下:
bean定義xml:
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:spring/beans/placeholder/attr.properties</value>
</property>
<property name="placeholderPrefix" value="${"></property>
<property name="placeholderSuffix" value="}"></property>
</bean>
<bean id="placeHolderBean" class="spring.beans.placeholder.PlaceHolderBean">
<property name="id" value="${placeholder.id}"></property>
<property name="name" value="${placeholder.name}"></property>
<property name="refBean" ref="${placeholder.ref}"></property>
</bean>
<bean id="refedBean" class="spring.beans.placeholder.RefedBean"></bean>自定義屬性文件attr.properties:
placeholder.id = 123 placeholder.name = cyy placeholder.ref = refedBean
2、PropertySourcesPlaceholderConfigurer
和PropertyPlaceholderConfigurer類似,但是它不能設(shè)置系統(tǒng)屬性加載模式,而是通過(guò)localOverride屬性來(lái)決定是否用自定義的屬性來(lái)覆蓋系統(tǒng)屬性。
3、context:property-placeholder標(biāo)簽
spring設(shè)計(jì)了context:property-placeholder標(biāo)簽來(lái)簡(jiǎn)化配置,它的原理跟上面兩種方式是一樣的,通過(guò)location屬性設(shè)置屬性文件路徑,如有多個(gè)用逗號(hào)分隔。
容器通過(guò)PropertyPlaceholderBeanDefinitionParser解析該標(biāo)簽,在解析時(shí)會(huì)把這個(gè)標(biāo)簽解析成PropertyPlaceholderConfigurer或PropertySourcesPlaceholderConfigurer,當(dāng)system-properties-mode設(shè)置為ENVIRONMENT系統(tǒng)變量?jī)?yōu)先時(shí)使用PropertySourcesPlaceholderConfigurer,否則使用PropertyPlaceholderConfigurer,
下面是這個(gè)標(biāo)簽的用法:
<context:property-placeholder
location="classpath:spring/beans/placeholder/attr.properties" />
<bean id="placeHolderBean" class="spring.beans.placeholder.PlaceHolderBean">
<property name="id" value="${placeholder.id}"></property>
<property name="name" value="${placeholder.name}"></property>
<property name="refBean" ref="${placeholder.ref}"></property>
</bean>
<bean id="refedBean" class="spring.beans.placeholder.RefedBean"></bean>屬性配置器在加載完自定義屬性之后會(huì)創(chuàng)建一個(gè)字符值處理器StringValueResolver,并且把加載到的屬性設(shè)置到這個(gè)處理器中,遍歷當(dāng)前容器中所有的bean定義,使用這個(gè)處理來(lái)處理屬性中未處理的占位符以及別名中的占位符,并且把該處理添加到容器中,為后面的bean解析提供占位符處理,見(jiàn)PlaceholderConfigurerSupport類中doProcessProperties方法的代碼:
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) {
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
// Check that we're not parsing our own bean definition,
// to avoid failing on unresolvable placeholders in properties file locations.
if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
try {
visitor.visitBeanDefinition(bd);
}
catch (Exception ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage(), ex);
}
}
}
// New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
beanFactoryToProcess.resolveAliases(valueResolver);
// New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot如何優(yōu)雅實(shí)現(xiàn)接口參數(shù)驗(yàn)證
為了保證參數(shù)的正確性,我們需要使用參數(shù)驗(yàn)證機(jī)制,來(lái)檢測(cè)并處理傳入的參數(shù)格式是否符合規(guī)范,所以本文就來(lái)和大家聊聊如何優(yōu)雅實(shí)現(xiàn)接口參數(shù)驗(yàn)證吧2023-08-08
六個(gè)Java集合使用時(shí)需要注意的事項(xiàng)
這篇文章主要為大家詳細(xì)介紹了六個(gè)Java集合使用時(shí)需要注意的事項(xiàng),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)java有一定的幫助,需要的可以參考一下2023-01-01
JAVA 數(shù)據(jù)結(jié)構(gòu)之Queue處理實(shí)例代碼
這篇文章主要介紹了JAVA 數(shù)據(jù)結(jié)構(gòu)之Queue處理實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
java工具類之實(shí)現(xiàn)java獲取文件行數(shù)
這篇文章主要介紹了一個(gè)java工具類,可以取得當(dāng)前項(xiàng)目中所有java文件總行數(shù),代碼行數(shù),注釋行數(shù),空白行數(shù),需要的朋友可以參考下2014-03-03
Java生成隨機(jī)數(shù)之Random與ThreadLocalRandom性能比較詳解
大家項(xiàng)目中如果有生成隨機(jī)數(shù)的需求,我想大多都會(huì)選擇使用Random來(lái)實(shí)現(xiàn),它內(nèi)部使用了CAS來(lái)實(shí)現(xiàn)。?實(shí)際上,JDK1.7之后,提供了另外一個(gè)生成隨機(jī)數(shù)的類ThreadLocalRandom,那么他們二者之間的性能是怎么樣的呢?本文就來(lái)詳細(xì)說(shuō)說(shuō)2022-12-12
Springboot項(xiàng)目如何兼容老的Spring項(xiàng)目問(wèn)題
這篇文章主要介紹了Springboot項(xiàng)目如何兼容老的Spring項(xiàng)目問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
springmvc HttpServletRequest 如何獲取c:forEach的值
這篇文章主要介紹了springmvc HttpServletRequest 如何獲取c:forEach的值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
java.nio.file.InvalidPathException異常解決
本人在ubuntu22.04的操作系統(tǒng)上,運(yùn)行java程序時(shí)創(chuàng)建一個(gè)文件,由于文件名稱中包含了中文,所以導(dǎo)致了程序拋出了java.nio.file.InvalidPathException的異常,感興趣的可以了解一下2025-09-09

