spring中 context:property-placeholder 導入多個獨立的 .properties配置文件?
Spring容器采用反射掃描的發現機制,在探測到Spring容器中有一個 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer的 Bean就會停止對剩余PropertyPlaceholderConfigurer的掃描(Spring 3.1已經使用PropertySourcesPlaceholderConfigurer替代 PropertyPlaceholderConfigurer了)。
換句話說,即Spring容器僅允許最多定義一個PropertyPlaceholderConfigurer(或<context:property-placeholder/>),其余的會被Spring忽略掉(其實Spring如果提供一個警告就好了)。
拿上來的例子來說,如果A和B模塊是單獨運行的,由於Spring容器都只有一個PropertyPlaceholderConfigurer, 因此屬性文件會被正常加載並替換掉。如果A和B兩模塊集成后運行,Spring容器中就有兩個 PropertyPlaceholderConfigurer Bean了,這時就看誰先誰后了, 先的保留,后的忽略!因此,只加載到了一個屬性文件,因而造成無法正確進行屬性替換的問題。
咋解決呢?
通配符解決
<context:property-placeholder location="classpath*:conf/conf*.properties"/>
_________________________________________________________________________________________
來源: http://www.cnblogs.com/beiyeren/p/3488871.html
一般使用PropertyPlaceholderConfigurer來替換占位符,例如:
<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配合更好。
另外需要注意以下幾點
1、在PropertyPlaceholderBeanDefinitionParser的父類中shouldGenerateId返回true,即默認會為每一個bean生成一個唯一的名字; 如果使用了兩個<context:property-placeholder則注冊了兩個PropertySourcesPlaceholderConfigurer Bean;所以不是覆蓋(而且bean如果同名是后邊的bean定義覆蓋前邊的);
2、PropertySourcesPlaceholderConfigurer本質是一個BeanFactoryPostProcessor,spring實施時如果發現這個bean實現了Ordered,則按照順序執行;默認無序;
3、此時如果給<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'的
4、默認情況下ignore-unresolvable;即如果沒找到的情況是否拋出異常。默認false:即拋出異常;
<context:property-placeholder location="classpath*:conf/conf_a.properties" ignore-unresolvable="false"/>
