Spring @Value注入值失敗,錯誤信息提示:Could not resolve placeholder

問題根源:

@Value("${wx.app.config.appid}") public Object appid;

異常信息:

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'wx.app.config.appid' in string value "${wx.app.config.appid}" at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174) at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236) at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:172) at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:823) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1084) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ... 79 more

解決方法:

Spring引入.properties文件的兩種方法(以下)

1.經過xml方式加載.properties文件

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
    <property name="locations"> <!-- PropertyPlaceholderConfigurer類中有個locations屬性,接收的是一個數組,即咱們能夠在下面配好多個properties文件 -->  
        <array>  <!-- 也能夠使用通配符的配置方式 -->
            <value>classpath:conn.properties</value>  
        </array>  
    </property>  
</bean>

2.經過註解方式加載.properties文件

<context:ignore-unresolvable="true" location="classpath:config/**/*.properties" system-properties-mode="OVERRIDE"/>
<!--location:表示屬性文件位置,多個之間經過如逗號/分號等分隔;--> <!--file-encoding:文件編碼;--> <!--ignore-resource-not-found:若是屬性文件找不到,是否忽略,默認false,即不忽略,找不到將拋出異常--> <!--ignore-unresolvable:是否忽略解析不到的屬性,若是不忽略,找不到將拋出異常--> <!--properties-ref:本地java.util.Properties配置--> <!--local-override:是否本地覆蓋模式,即若是true,那麼properties-ref的屬性將覆蓋location加載的屬性--> <!--system-properties-mode:系統屬性模式,ENVIRONMENT(默認),NEVER,OVERRIDE--> <!--ENVIRONMENT:將使用Spring 3.1提供的PropertySourcesPlaceholderConfigurer,其餘狀況使用Spring 3.1以前的PropertyPlaceholderConfigurer--> <!--OVERRIDE: PropertyPlaceholderConfigurer使用,由於在spring 3.1以前版本是沒有Enviroment的,因此OVERRIDE是spring 3.1以前版本的Environment--> <!--NEVER:只查找properties-ref、location;--> <!--order:當配置多個<context:property-placeholder/>時的查找順序-->

知道了怎麼配置,就知道本身有沒有配置錯誤,若是配置沒有問題,那麼就繼續找問題,Could not resolve placeholder佔位符不能被解析,那就是沒有在.properties中找到要注入的值了,原來是在xml裏面配置了2個ignore-unresolvable,這就是定位問題所在了。java

<!-- 配置數據庫相關參數properties的屬性:${url} -->
<context:property-placeholder location="classpath*:/mybatis/db.properties"/>
<!-- 引入property文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:config/config-wxapp.properties" ignore-resource-not-found="true"/>

一個是引入配置文件.properties,一個是引入db配置文件.properties,其實配置多個並非報錯的主要問題所在,是由於spring的加載機制,原來是Spring容器採用反射掃描的發現機制,在探測到Spring容器中有一個org.springframework.beans.factory.config.PropertyPlaceholderConfigurer的Bean就會中止對剩餘PropertyPlaceholderConfigurer的掃描(Spring 3.1已經使用PropertySourcesPlaceholderConfigurer替代PropertyPlaceholderConfigurer了),因此根據加載的順序,配置的第二個property-placeholder就被沒有被spring加載,我想引入的config-wxapp.properties就沒有被引入,因此在使用@Value注入的時候佔位符就解析不了...解決方法就是把2個property-placeholder註解配置合併在一塊兒就行了spring

<!-- 引入property文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath*:config/config-*.properties,classpath*:mybatis/db.properties" ignore-resource-not-found="true"/>
相關文章
相關標籤/搜索