Spring 3.0中的多个属性文件

Tom*_*yre 19 java spring properties

我正在开发一个带有几个独立模块的项目,每个模块都有自己的应用程序上下文属性文件.我希望能够加载所有这些属性,以便它们可以用于Spring的占位符解析.

以前的问题已经提到了这一点,并有一个很好的博客文章在这里,描述了如何在各个环境中使用提供一个PropertyPlaceholderConfigurer,按优先级排序它们并设置ignoreUnresolveablePlaceholders为true,以便这些属性文件可以交叉引用对方没有吹起来.

但是,这并没有解决我的问题,因为我也希望能够使用我正在加载的属性来进行一些自定义占位符解析(从我正在解析的一些yaml文件).这需要使用PropertyPlaceholderHelper,它需要将Properties对象作为参数.

据我所知,潜在的解决方案是:

1)将所有属性文件合并到一个属性bean中.然后可以使用它来创建PropertyPlaceholderConfigurer(用于Spring的内部占位符解析)并与PropertyPlaceholderHelper一起使用(用于我自己的占位符解析)

2)以某种方式配置PropertyPlaceholderHelper以使用PropertyPlaceholderConfigurers持有的属性集及其层次结构,如果我继续并遵循该博客帖子的建议.

不幸的是,我无法弄清楚如何做其中任何一个.任何帮助将不胜感激!

PS看起来Spring 3.1在这里将是一个很大的帮助......遗憾的是我们还没有准备好转向它,所以我仍然需要一个解决方案让我度过难关!

****编辑****

谢谢你到目前为止的答案.它们是很好的答案,但遗憾的是不会对我有所帮助,因为(并且对于之前没有提到这一点道歉)我们目前正在将我们项目的核心模块与非核心模块分开.这意味着核心模块及其应用程序上下文无法对属性文件的名称进行硬编码.令人沮丧的是,Spring的类路径扫描似乎被打破了,所以"classpath*:*.properties"类型的通配符仅在构建单个模块时起作用,而不是顶级项目(我相信这是一个已知问题).

问题是如何将非核心模块中定义的属性文件合并到核心模块中定义的现有属性文件中.目前我正在使用BeanPostProcessor - 我只是想知道是否有更简单/更优雅的方法来做到这一点?

谢谢

mre*_*isz 9

您可以非常轻松地将多个属性文件收集到一个bean中:

<bean id="allProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="singleton" value="true"/>
  <property name="ignoreResourceNotFound" value="true"/>
  <property name="locations">
    <list>
      <value>classpath*:default.properties</value>
      <value>classpath*:overrides.properties</value>
      <value>file:${APP_HOME}/**/*.properties</value>
    </list>
  </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

此特定示例将收集APP_HOME中类路径和属性文件上的所有default.properties,overrides.properties.现在,您可以从ProperyPlaceholderConfigurer或您的自定义后处理器中引用此bean.


Pra*_*ate 7

以下代码段应该可以帮助您入门

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="corePlaceHolder">
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="searchSystemEnvironment" value="true"/>
    <property name="locations">
        <list>
            <value>classpath*:config/*/config1/*.properties</value>
            <value>classpath*:config/*/config2/*.properties</value>
            <value>classpath*:config/*/config3/*.properties</value>
            <value>classpath*:custom.properties</value>
        </list>
    </property>
</bean>     
Run Code Online (Sandbox Code Playgroud)

您可以将属性文件存储在以下层次结构中,确保可以通过类路径访问配置

config
  config1
     a.properties
  config2
     b.properties
  config3
     c.properties
custom.properties
Run Code Online (Sandbox Code Playgroud)


The*_*tor 6

这就是你需要做的一切:

<context:property-placeholder location="first.properties" order="0" ignore-unresolvable="true"/>
<context:property-placeholder location="second.properties" order="0" ignore-unresolvable="true"/>
<context:property-placeholder location="empty.properties" order="1"/>
Run Code Online (Sandbox Code Playgroud)

问题很简单:如果property-placeholder没有某个属性的值,它将抛出异常,即使存在其他property-placeholder.

解决方案用于order了解哪个是最后一个property-placeholder并设置ignore-unresolvable="true"在所有其他的上,以便每个人property-placeholder都有机会提供值.在多模块项目中,最后一个property-placeholder可能为空或提供failafe-defaults.

注意:如果将所有property-placeholder设置为ignore-unresolvable="true"Spring,则只传递您编写的内容而不抛出异常.当然,如果你期望它不是String你的话,你肯定会java.lang.NumberFormatException: For input string: "${something}"在格式转换过程中得到一个例子.

注意:将仅使用具有特定属性值的第一个(最低的一个order)property-placeholder.如果你想覆盖性能使用更大order的范围比01property-override.

使用Spring 3.2.1测试,但所有提到的属性都存在于3.0中.请参阅PropertyPlaceholderConfigurer的JavaDoc