Is it possible to have multiple PropertyPlaceHolderConfigurer in my applicationContext?

JavaSpring

Java Problem Overview


I need to load a specific applicationContext.xml file according to a given system property. This itself loads a file with the actual configuration. Therefore I need two PropertyPlaceHolderConfigurer, one which resolves the system param, and the other one within the actual configuration.

Any ideas how to do this?

Java Solutions


Solution 1 - Java

Yes you can do more than one. Be sure to set http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html#setIgnoreUnresolvablePlaceholders(boolean)">ignoreUnresolvablePlaceholders</a> so that the first will ignore any placeholders that it can't resolve.

<bean id="ppConfig1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="ignoreUnresolvablePlaceholders" value="true"/>
   <property name="locations">
    <list>
   	         <value>classpath*:/my.properties</value>
    </list>
  </property>
</bean>

<bean id="ppConfig2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="ignoreUnresolvablePlaceholders" value="false"/>
   <property name="locations">
    <list>
   	         <value>classpath*:/myOther.properties</value>
    </list>
  </property>
</bean>

Depending on your application, you should investigate systemPropertiesMode, it allows you to load properties from a file, but allow the system properties to override values in the property file if set.

Solution 2 - Java

Beware -- there might be a bug related to multiple configurers. See http://jira.spring.io/browse/SPR-5719 for more details.

I'm unable to get multiple to work locally... but I'm not yet blaming anyone but myself.

Solution 3 - Java

Another solution is to use placeholderPrefix property of PropertyPlaceholderConfigurer. You specify it for the second (third, fourth...) configurer, and then prefix all your corresponding placeholders, thus there will be no conflict.

<bean id="mySecondConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
		p:location="classpath:/myprops.properties" 
		p:placeholderPrefix="myprefix-"/>

<bean class="com.mycompany.MyClass" p:myprop="${myprefix-value.from.myprops}"/>

Solution 4 - Java

You can't do this directly, and this JIRA issue from Spring explains why (check the comment from Chris Beams for a detailed explanation):

https://jira.springsource.org/browse/SPR-6428

However, he does provide a workaround using Spring 3.1 or later, which is to use the PropertySourcesPlaceholderConfigurer class instead of PropertyPlaceholderConfigurer class.

You can download a Maven-based project that demonstrates the problem and the solution from the Spring framework issues github:

https://github.com/SpringSource/spring-framework-issues

Look for the issue number, SPR-6428, in the downloaded projects.

Solution 5 - Java

On my own side, playing with PropertyPlaceholderConfigurer both properties :

  • order (should be lower for first accessed/parsed PPC)
  • ignoreUnresolvablePlaceholders ("false" for first accessed/parsed PPC, "true" for next one)
  • and also give 2 distinct id(s) to both PPC (to avoid one to be overwritten by the other)

works perfectly

Hope it helps

Solution 6 - Java

We have the following approach working:

<util:properties id="defaultProperties">
    <prop key="stand.name">DEV</prop>
    <prop key="host">localhost</prop>
</util:properties>
<context:property-placeholder 
    location="file:${app.properties.path:app.properties}" 
    properties-ref="defaultProperties"/>

System property app.properties.path can be used to override path to config file.

And application bundles some default values for placeholders that cannot be defined with defaults in common modules.

Solution 7 - Java

Just giving 2 distinct ids worked for me. I am using spring 3.0.4.

Hope that helps.

Solution 8 - Java

In case, you need to define two PPC's (like in my situation) and use them independently. By setting property placeholderPrefix, you can retrieve values from desired PPC. This will be handy when both set of PPC's properties has same keys, and if you don't use this the property of ppc2 will override ppc1.

Defining your xml:

<bean name="ppc1"
	class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="properties" ref="ref to your props1" />
		<property name="placeholderPrefix" value="$prefix1-{" />
	</bean>
<bean name="ppc2"
	class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="properties" ref="ref to your props2" />
		<property name="placeholderPrefix" value="$prefix2-{" />
	</bean>

Retrieving during Run time:

@Value(value = "$prefix1-{name}")
private String myPropValue1;

@Value(value = "$prefix2-{name}")
private String myPropValue2;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMauliView Question on Stackoverflow
Solution 1 - JavaflickenView Answer on Stackoverflow
Solution 2 - JavaTrentonView Answer on Stackoverflow
Solution 3 - JavaweekensView Answer on Stackoverflow
Solution 4 - Javauser1071914View Answer on Stackoverflow
Solution 5 - JavaSylvainRView Answer on Stackoverflow
Solution 6 - JavaVadzimView Answer on Stackoverflow
Solution 7 - Javas91gView Answer on Stackoverflow
Solution 8 - JavaJava_deepView Answer on Stackoverflow