spring中 context:property-placeholder 導入多個獨立的 .properties配置文件?html
Spring容器採用反射掃描的發現機制,在探測到Spring容器中有一個 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer的 Bean就會中止對剩餘PropertyPlaceholderConfigurer的掃描(Spring 3.1已經使用PropertySourcesPlaceholderConfigurer替代 PropertyPlaceholderConfigurer了)。spring
換句話說,即Spring容器僅容許最多定義一個PropertyPlaceholderConfigurer(或<context:property-placeholder/>),其他的會被Spring忽略掉(其實Spring若是提供一個警告就行了)。
拿上來的例子來講,若是A和B模塊是單獨運行的,因爲Spring容器都只有一個PropertyPlaceholderConfigurer, 所以屬性文件會被正常加載並替換掉。若是A和B兩模塊集成後運行,Spring容器中就有兩個 PropertyPlaceholderConfigurer Bean了,這時就看誰先誰後了, 先的保留,後的忽略!所以,只加載到了一個屬性文件,於是形成沒法正確進行屬性替換的問題。post
咋解決呢?url
通配符解決spa
<context:property-placeholder location="classpath*:conf/conf*.properties"/> htm
_________________________________________________________________________________________blog
來源: http://www.cnblogs.com/beiyeren/p/3488871.html開發
通常使用PropertyPlaceholderConfigurer來替換佔位符,例如:get
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:com/foo/strategy.properties</value> </property> <property name="properties"> <value>custom.strategy.class=com.foo.DefaultStrategy</value> </property> </bean>
spring 2.5以後,可使用
<context:property-placeholder location="classpath:com/foo/jdbc.properties"/>
其本質是註冊了一個PropertyPlaceholderConfigurer(3.1以前)或者是PropertySourcesPlaceholderConfigurer(3.1以後)
Tip:
PropertyPlaceholderConfigurer內置的功能很是豐富,若是它未找到${xxx}中定義的xxx鍵,它還會去JVM系統屬性(System.getProperty())和環境變量(System.getenv())中尋找。經過啓用systemPropertiesMode和searchSystemEnvironment屬性,開發者可以控制這一行爲。
而PropertySourcesPlaceholderConfigurer在此基礎上會和Environment and PropertySource配合更好。
另外須要注意如下幾點
一、在PropertyPlaceholderBeanDefinitionParser的父類中shouldGenerateId返回true,即默認會爲每個bean生成一個惟一的名字; 若是使用了兩個<context:property-placeholder則註冊了兩個PropertySourcesPlaceholderConfigurer Bean;因此不是覆蓋(並且bean若是同名是後邊的bean定義覆蓋前邊的); 二、PropertySourcesPlaceholderConfigurer本質是一個BeanFactoryPostProcessor,spring實施時若是發現這個bean實現了Ordered,則按照順序執行;默認無序; 三、此時若是給<context:property-placeholder加order屬性,則會反應出順序,值越小優先級越高即越早執行; 好比 <context:property-placeholder order="2" location="classpath*:conf/conf_a.properties"/> <context:property-placeholder order="1" location="classpath*:conf/conf_b.properties"/> 此時會先掃描order='1' 的,若是沒有掃描order='2'的 四、默認狀況下ignore-unresolvable;即若是沒找到的狀況是否拋出異常。默認false:即拋出異常; <context:property-placeholder location="classpath*:conf/conf_a.properties" ignore-unresolvable="false"/>