spring的多個PropertyPlaceholderConfigurer實例裝配的問題


1. 默認情況下,使用PropertyPlaceholderConfigurer多實例裝配出現異常

    在項目中嘗試 在不同的spring的配置文件中分別引入相應的properties文件,這樣會在spring配置文件中配置多個PropertyPlaceholderConfigurer實例,但是這樣使用的話就會出現key找不到的問題,異常信息如下:

“ Could not resolve placeholder 'key2”

信息: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@38882d9a: defining beans [propertyConfigurer1,propertyConfigurer2,serviceA,serviceB,resourceServiceImpl]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'serviceA' defined in class path resource [applicationContext.xml]: Could not resolve placeholder 'key2'
    at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:287)
    at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:75)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:663)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:638)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:407)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at org.simonme.srcstudy.spring3.demo.service.BeanAssemblyTest.main(BeanAssemblyTest.java:34)

配置形式如下(為了分析問題,配置形式做了簡化,但是體現出了原本的意思):

<bean id="propertyConfigurer1"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>
                classpath:conf/test/test1.properties
            </value>
        </list>
    </property>
</bean>

<bean id="propertyConfigurer2"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>
                classpath:conf/test/test2.properties
            </value>
        </list>
    </property>
</bean>

<bean id="serviceA" class="org.simonme.srcstudy.spring3.demo.service.impl.ServiceAImpl">
    <property name="field" value="field4AInstacne"/>
    <property name="key1" value="${key1}"/>
    <property name="key2" value="${key2}"/>
</bean>

Java的service代碼如下:

public class ServiceAImpl implements ServiceA
{
    
    private String field;
    
    private String key1;
    
    private String key2;
    
    /**
     * 模擬返回測試數據
     * @return
     */
    @Override
    public String queryA()
    {
        System.out.println("key1:" + key1);
        System.out.println("key2:" + key2);
        return "Query A Result" + field;
    }

    public String getField()
    {
        return field;
    }

    public void setField(String field)
    {
        this.field = field;
    }

    public String getKey1()
    {
        return key1;
    }

    public void setKey1(String key1)
    {
        this.key1 = key1;
    }

    public String getKey2()
    {
        return key2;
    }

    public void setKey2(String key2)
    {
        this.key2 = key2;
    }
}

 

2. 如何裝配能不出異常

如果仍然需要使用兩個(或多個)PropertyPlaceholderConfigurer實例進行裝配,怎樣才能解決上面的異常?

<bean id="propertyConfigurer1"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
    <property name="locations">
        <list>
            <value>
                classpath:conf/test/test1.properties
            </value>
        </list>
    </property>
</bean>

<property name="ignoreUnresolvablePlaceholders" value="true"/>

加上上面的一行,表示可以忽略未解析到的占位符。這樣就不會報錯。如果對每個PropertyPlaceholderConfigurer實例都配置了這句話(忽略未解析占位符錯誤),那什么時候檢查未解析到的占位符呢?

 

3. 如何解決占位符未配置的檢查問題?不完美

    對於未解析到的占位符,可以通過order屬性來調整bean裝配的優先級,然后在最后裝配的PropertyPlaceholderConfigurer實例上面啟用未解析到的占位符檢查。

4.使PropertyPlaceholderConfigurer多實例裝配出現異常對應的spring的代碼在哪里

    分析上述問題涉及的spring代碼主要在哪里?

在spring bean裝配時,一個PropertyPlaceholderConfigurer就是一個后置處理器BeanFactoryPostProcessor。在裝配完PropertyPlaceholderConfigurer之后,就會觸發org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor>, ConfigurableListableBeanFactory)方法,代碼如下:

/**
 * Invoke the given BeanFactoryPostProcessor beans.
 */
private void invokeBeanFactoryPostProcessors(
        Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

每調用完一個BeanFactoryPostProcessor之后,就會去解析所有的bean中引用properties的占位符,這時就會出現占位符不能解析的問題(不能解析的占位在后面的BeanFactoryPostProcessor中,也就是PropertyPlaceholderConfigurer實例)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM