Spring 3.1 PropertySourcesPlaceholderConfigurer and conditional import

11,206

Solution 1

Footnote [2] of your link:

[2]: Because processing of <import/> elements necessarily occurs before BeanFactoryPostProcessors are invoked, meaning that even PropertyPlaceholderConfigurer could not help here. Because the Environment and its set of PropertySources are configured before container refresh, placeholders in elements can be resolved against the Environment without any lifecycle issues.

UPDATE:

According to the javadoc for PropertySourcesPlaceholderConfigurer, PropertySourcesPlaceholderConfigurer is a BeanFactoryPostProcessor, so what the footnote really says is that the import is resolved before the PropertySourcesPlaceholderConfigurer is installed, so it will not work either (in fact, at the time the <import/> is resolved, the configurer might not even exist yet!) Yes, when it is installed it will look at the Environment, but you cannot use it to resolve inside an <import/>, because at that time no postprocessors are operative. And that includes PropertySourcesPlaceholderConfigurer.

Basically Spring XML context setup goes more or less like this:

  1. Context is created.
  2. Environment is set.
  3. XML is read (all XML, resolving imports if necessary). Bean definitions are created.
  4. BeanFactoryPostProcessors are installed and invoked, processing bean definitions.
  5. BeanPostProcessors are installed.
  6. Beans are instantiated according to the bean definitions. BeanPostProcessors are applied.

This is a similar problem as that which causes that you cannot use the order property of many postprocessors to apply a BeanPostProccesor before a BeanFactoryPostProcessor (to do something like make a PropertyPlaceholderConfigurer resolve placeholders from a @PersistenceContext): the behaviour is hardcoded in the Spring application context, so you have to work around it by specializing some Spring classes.

Solution 2

I think you are mis-reading the blog a little @Kurt - It should be resolved IF the property source containing the property is present before the bean definitions are starting to be created.

So the way to get your import to resolve will these two ways: 1. set an environment variable with this parameter (-Dlogin.security=dev) which will be registered as a property source by default
2. to register a file as a property source programatically, mentioned in the blog article by writing a custom ApplicationContextInitializer to register your property source - you should be able to use a ResourcePropertySource to register your file based property source

Share:
11,206
Kurt Peterschmidt
Author by

Kurt Peterschmidt

Updated on June 17, 2022

Comments

  • Kurt Peterschmidt
    Kurt Peterschmidt almost 2 years

    Looking at the new spring property support in 3.1 ( http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/ ), it looks like this should be possible:

    <context:property-placeholder location="/WEB-INF/application-customer-dev.properties,classpath:application-customer.properties" ignore-resource-not-found="true"/>
    
    <import resource="classpath*:com/x/core/security/security-${login.security}.xml"/>
    

    where login.security is in application-customer-dev.properties as:

    login.security=dev
    

    (and security-dev.xml does exist in the appropriate place). I am missing something though, as login.security is not able to be resolved. I would expect this behavior in versions of spring prior to 3.1, but it looks like this should be valid with 3.1 (which we are using)?

  • Kurt Peterschmidt
    Kurt Peterschmidt about 12 years
    Yes, PropertyPlaceholderConfigurer could not help (as was the default pre-spring 3.1), but the new PropertySourcesPlaceholderConfigurer (spring 3.1) will look in the Environment to resolve those values. That footnote is basically confirming it should work.
  • gpeche
    gpeche about 12 years
    @KurtPeterschmidt I have updated my answer, hope it is somewhat clearer now
  • Kurt Peterschmidt
    Kurt Peterschmidt about 12 years
    Thanks for the additional explanation.
  • Kurt Peterschmidt
    Kurt Peterschmidt about 12 years
    Perhaps it was just my desire for it to work in this manner that clouded my interpretation of the blog post... :)