【问题标题】:property-placeholder location from another property来自另一个属性的属性占位符位置
【发布时间】:2009-08-21 11:11:15
【问题描述】:

我需要在程序运行之前从我不知道的位置将一些属性加载到 Spring 上下文中。

所以我想如果我有一个没有位置的 PropertyPlaceholderConfigurer,它会从系统属性中读取my.location,然后我可以在上下文中使用该位置:property-placeholder

这样

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>    
<context:property-placeholder location="${my.location}"/>

但这不起作用,location="classpath:${my.location}"也不起作用

保罗

【问题讨论】:

  • 你不能像这样组合两个占位符——它们是 BeanFactoryPostProcessors,如果你明白我的意思,它们不能相互处理。
  • 是的,我认为我的问题是这样的
  • 实际上,这听起来像是对 PropertyPlaceHolderConfigurer 的增强,可能值得在 Spring JIRA 中作为功能请求提交。

标签: java spring


【解决方案1】:

您可以使用稍微不同的方法来做到这一点。这是我们如何配置它。我加载默认属性,然后用可配置位置的属性覆盖它们。这对我来说效果很好。

<bean id="propertyPlaceholderConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="locations">
            <list>
                <value>classpath:site/properties/default/placeholder.properties
                </value>
                <value>classpath:site/properties/${env.name}/placeholder.properties
                </value>
            </list>
        </property>
    </bean>

【讨论】:

    【解决方案2】:

    这里的问题是您正在尝试使用属性占位符语法配置属性占位符 :) 这有点像先有鸡还是先有蛋的情况 - spring 无法解析您的 ${my.location} 占位符,直到它被配置属性占位符。

    这并不令人满意,但您可以通过使用更明确的语法来避免它:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceHolderConfigurer">
       <property name="location">
          <bean class="java.lang.System" factory-method="getenv">
             <constructor-arg value="my.location"/>
          </bean>
       </property>
    </bean>
    

    【讨论】:

    • 使用 Spring 3.1.3 对我不起作用:org.springframework.beans.NotWritablePropertyException: Invalid property 'location' of bean class [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer]: Bean property 'location' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?