使用spring的<context:property-placeholder location="/WEB-INF/redis.properties"/>讀取properties配置文件報錯 Could not resolve placeholder
項目結構
配置
啟動報錯
順着這個錯誤向上找發現.properties文件沒有全部加載, log4j.properties在web.xml中配置加載, jdbc.properties和redis.properties文件都配置在application.xml文件中,
從控制台上可以發現redis.properties文件並沒有被加載
INFO: Set web app root system property: 'webapp.root' = [D:\soft\MyEclipse Professional2013workspace\.metadata\.me_tcat\webapps\zjx-springmvc\]
七月 24, 2016 12:16:29 上午 org.apache.catalina.core.ApplicationContext log
INFO: Initializing log4j from [D:\soft\MyEclipse Professional2013workspace\.metadata\.me_tcat\webapps\zjx-springmvc\WEB-INF\log4j.properties]
七月 24, 2016 12:16:29 上午 org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
[INFO][2016-07-24 00:16:29] org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:305) Root WebApplicationContext: initialization started
[INFO][2016-07-24 00:16:30] org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:578) Refreshing Root WebApplicationContext: startup date [Sun Jul 24 00:16:30 CST 2016]; root of context hierarchy
[INFO][2016-07-24 00:16:31] org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:317) Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
[INFO][2016-07-24 00:16:35] org.springframework.core.io.support.PropertiesLoaderSupport.loadProperties(PropertiesLoaderSupport.java:172) Loading properties file from ServletContext resource [/WEB-INF/jdbc.properties]
[WARN][2016-07-24 00:16:35] org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'jedisPoolConfig' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Could not resolve placeholder 'redis.maxIdle' in string value "${redis.maxIdle}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'redis.maxIdle' in string value "${redis.maxIdle}"
[ERROR][2016-07-24 00:16:35] org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:351) Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'jedisPoolConfig' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Could not resolve placeholder 'redis.maxIdle' in string value "${redis.maxIdle}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'redis.maxIdle' in string value "${redis.maxIdle}"
解決辦法:
spring的xml配置文件中當有多個*.properties文件需要加載時。需要這樣
方案1: 不建議使用(耦合性太大不利於拆分項目)
將多個.properties文件合到一個.properties文件中
方案2: 在<context:property-placeholder location="/WEB-INF/jdbc.properties"/>中加 ignore-unresolvable="true"
原因:
Spring容器采用反射掃描的發現機制,在探測到Spring容器中有一個 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer的 Bean就會停止對剩余PropertyPlaceholderConfigurer的掃描(Spring 3.1已經使用PropertySourcesPlaceholderConfigurer替代 PropertyPlaceholderConfigurer了)。
而<context:property-placeholder/>這個基於命名空間的配置,其實內部就是創建一個PropertyPlaceholderConfigurer Bean而已。換句話說,即Spring容器僅允許最多定義一個PropertyPlaceholderConfigurer(或<context:property-placeholder/>),其余的會被Spring忽略掉(其實Spring如果提供一個警告就好了)。
方案3: 其他加載資源文件方式
#加載jdbc資源文件
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true" /> </bean>
#加載redis資源文件
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:redis.properties</value><!-- 如果是類路徑下這樣加載 -->
<!--<value>/WEB-INF/redis.properties</value>--><!-- 如果是WEB-INFO路徑下這樣加載 --> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true" /> </bean>
只要保證ignoreUnresolvablePlaceholders都為true,或這最后一個加載的為false,之前的都為true即可。
總結:
無論是方案2還是方案三即: ignore-unresolvable="true" 和 <property name="ignoreUnresolvablePlaceholders" value="true" /> 這兩個屬性值必須為true
