zoukankan      html  css  js  c++  java
  • 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实例)。

  • 相关阅读:
    商业智能添加维度智能简介
    1049 数列的片段和 (20 分)
    1045 快速排序 (25 分)
    1044 火星数字 (20 分)
    1136 A Delayed Palindrome (20 分)
    1128 N Queens Puzzle (20 分)
    1124 Raffle for Weibo Followers (20 分)
    1125 Chain the Ropes (25 分)
    1121 Damn Single (25 分)
    1116 Come on! Let's C (20 分)
  • 原文地址:https://www.cnblogs.com/simoncook/p/5652328.html
Copyright © 2011-2022 走看看