我的applicationContext中可以有多个PropertyPlaceHolderConfigurer吗?

时间:2009-03-26 16:50:45

标签: java spring

我需要根据给定的系统属性加载特定的applicationContext.xml文件。这本身会加载具有实际配置的文件。因此,我需要2个PropertyPlaceHolderConfigurer,一个解析系统参数,另一个解析实际配置。

任何想法如何做到这一点?

8 个答案:

答案 0 :(得分:76)

是的,你可以做多个。请务必设置ignoreUnresolvablePlaceholders,以便第一个忽略任何无法解析的占位符。

<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>

根据您的应用程序,您应该调查systemPropertiesMode,它允许您从文件加载属性,但允许系统属性覆盖属性文件中的值(如果已设置)。

答案 1 :(得分:7)

注意 - 可能存在与多个配置程序相关的错误。有关详细信息,请参阅http://jira.spring.io/browse/SPR-5719

我无法让多人在当地工作......但我还没有责怪别人,除了我自己。

答案 2 :(得分:6)

另一种解决方案是使用PropertyPlaceholderConfigurer的placeholderPrefix属性。您为第二个(第三个,第四个......)配置器指定它,然后为所有相应的占位符添加前缀,因此不会发生冲突。

<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}"/>

答案 3 :(得分:3)

你不能直接这样做,Spring的这个JIRA问题解释了原因(查看Chris Beams的评论以获得详细解释):

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

但是,他确实使用Spring 3.1或更高版本提供了一种解决方法,即使用PropertySourcesPlaceholderConfigurer类而不是PropertyPlaceholderConfigurer类。

您可以下载一个基于Maven的项目来演示问题,Spring框架中的解决方案会发布github:

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

在下载的项目中查找问题编号SPR-6428。

答案 4 :(得分:3)

在我自己的一边,使用PropertyPlaceholderConfigurer两个属性:

  • 订单(首次访问/解析的PPC应该更低)
  • ignoreUnresolvablePlaceholders(首次访问/解析的PPC为“false”,下一次为“true”)

  • 并且还为两个PPC提供2个不同的id(以避免一个被另一个覆盖)

完美运作

希望有所帮助

答案 5 :(得分:0)

我们有以下方法:

<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"/>

系统属性app.properties.path可用于覆盖配置文件的路径。

应用程序捆绑了一些默认值,这些占位符无法在通用模块中使用默认值进行定义。

答案 6 :(得分:0)

给我两个不同的ID。我使用的是spring 3.0.4。

希望有所帮助。

答案 7 :(得分:0)

以防万一,您需要定义两个PPC(就像我的情况一样)并独立使用它们。通过设置属性 placeholderPrefix ,您可以从所需的PPC中检索值。当两组PPC属性具有相同的键时,这将非常方便;如果您不使用它,则ppc2的属性将覆盖ppc1。

定义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>

在运行时检索:

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

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