Announcement Announcement Module
Collapse
No announcement yet.
Strange behavior with Java-centric configuration of PropertyPlaceholderConfigurer Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Strange behavior with Java-centric configuration of PropertyPlaceholderConfigurer

    Consider the following use of a combined PropertySourcesPlaceholderConfigurer and a legacy PropertyPlaceholderConfigurer defined in xml:

    Code:
    @Configuration
    @ImportResource("classpath:beans.spring.xml")
    public class MyConfiguration {
        @Bean
        public static PropertySourcesPlaceholderConfigurer pspc () {
            return new PropertySourcesPlaceholderConfigurer();
        }
    }
    Code:
    <bean id="test.propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="ignoreResourceNotFound" value="true" />
        <property name="locations">
            <set>
                <value>classpath:foo.properties</value>
            </set>
        </property>
    </bean>
        
    <bean id="test.foo" class="Foo">
        <property name="foo" value="${foo}"/>
    </bean>
    If I construct a new AnnotationConfigApplicationContext(MyConfiguration .class) I get the following error:

    org.springframework.beans.factory.BeanDefinitionSt oreException: Invalid bean definition with name 'test.foo' defined in class path resource [beans.spring.xml]: Could not resolve placeholder 'foo' in string value [${foo}]

    However, If I modify MyConfiguration to use a static inner class for the ImportResource, it works:

    Code:
    @Configuration
    public class MyConfiguration
    {
        @Configuration
        @ImportResource("classpath:beans.spring.xml")
        static class InnerConfiguration {}
        
        @Bean
        public static PropertySourcesPlaceholderConfigurer pspc () {
            return new PropertySourcesPlaceholderConfigurer();
        }
    }
    It also works if I remove the pspc bean, but I need that for further work. I don't understand this behavior, and I'm concerned about doing further work with a mixture of xml and java configuration. I'm using spring 3.1.2.

    jeff

  • #2
    It turns out it's an ordering issue. In the first example above, the pspc is ordered first, and since it uses the default of ignoreUnresolvablePlaceholders=true, it fails when resolving properties in beans.spring.xml. In the workaround, the static inner class forces beans.spring.xml to be loaded first, ensuring that the PropertyPlaceHolder defined in the xml is ordered before the pspc. I suppose a better workaround is to explicitly set the order field of the pspc.

    I think this is an interesting observation of some of the caveats of migrating from xml to java config. With xml, the order of bean definitions is more apparent from the lexical order of the file.

    Comment


    • #3
      I had similar issue and kept wondering what went wrong. Thanks for the suggestion to set explicitly order. In my case, I wanted my pspc to run first. So I set the minimum value as in the code below.

      Code:
      @Bean
      public static PropertySourcesPlaceholderConfigurer pspc () {
        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
        pspc.setOrder(Integer.MIN_VALUE);
        return pspc;
      }
      One correction to the previous reply. default value of ignoreUnresolvablePlaceholders is false.

      Comment

      Working...
      X