当文件列表是参数时,使用 Spring 加载多个属性文件时出现问题<util:properties />



我们需要将多个属性文件加载在一起,并将它们用作属性的一个来源。<util:properties>允许您通过逗号分开的文件列表,到目前为止一切正常。因此,以下内容很好:

<util:properties loaction="conf/file1.properties,conf/file2.properties,abc-*.properties" />

但是,在我们的情况下,属性文件列表尚未修复,它来自以前加载的另一个主属性文件。我们想将该列表传递给<util:properties>作为参数,但它不起作用。

<util:properties location="${allPropertiesFiles}" />

其中${allPropertiesFiles}定义为

allPropertiesFiles=conf/file1.properties,conf/file2.properties,abc-*.properties

这是由于文件列表中的逗号而失败。它将它们视为一个单个文件名并抛出filenotfoundexception。

我想知道春天在什么时候试图通过逗号拆分文件,看来它在解决$ {allpropertiesfiles}之前发生。例如,如果我在下面做得很好,但这对我们来说不是一个实用的解决方案,因为我们不知道该列表中包含多少个文件。

<util:properties location="${propFile.location1},${propFile.location2},${propFile.location3}" />

更新:

在解决 ${...}中的属性值之前,这似乎是春季问题。我什至尝试使用Spring EL将其拆分,但它会通过解析有效的EL再次失败,因为它首先基于",然后评估表达式。以下示例失败,El Parse例外:

<util:properties location="#{'${allPropertiesFiles}'.split(',')}" />

fyi这个观察结果是弹簧4.2.x。任何建议都非常感谢。

您是否尝试用双引号将变量值包围?在一个小测试中,这就像魅力一样:

ApplicationContext:

<bean id="test" class="de.de.proptest.Test">
    <property name="p" ref="props" />
</bean>
<util:properties location="${props}" id="props" />

我有2个属性文件,A。properties具有内容:

a=1

和b。与内容:

的Properties
b=2

使用JVM参数

-Dprops="file:/home/dominik/sandbox/proptest/a.properties, file:/home/dominik/sandbox/proptest/b.properties"

我将获得以下输出(剪切到有趣的点):

Mar 11, 2017 1:32:11 PM org.springframework.beans.factory.config.PropertiesFactoryBean loadProperties
INFO: Loading properties file from URL [file:/home/dominik/sandbox/proptest/a.properties]
Mar 11, 2017 1:32:11 PM org.springframework.beans.factory.config.PropertiesFactoryBean loadProperties
INFO: Loading properties file from URL [file:/home/dominik/sandbox/proptest/b.properties]
Test [p={b=2, a=1}]

所以,我在我的问题上找到了解决方案/解决方案,并想在这里分享。

util:propertiescontext:property-placeholder的BEAN解析器将location属性的给定字符串值划分为,。它发生在财产分辨率发生之前。因此

因此,我决定直接使用PropertiesFactoryBean,而不是使用<util:properties>,并将位置设置为参数。这解决了bean定义在弹簧中的构建方式,它使用弹簧默认的bean解析器。然后,我提供了Spring ResourceArrayPropertyEditor的自定义版本,该版本将String转换为Resource[]。属性编辑器在转换为Resource[]时处理逗号分隔的字符串。

这是我的上下文XML:

    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry key="org.springframework.core.io.Resource[]" value="com.mycompany.CustomResourceArrayPropertyEditor"/>
            </map>
        </property>
    </bean> 
    <bean id="allPropertiesFromFiles" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
            <property name="locations" value="${propertiesFile.locations}" />
    </bean>

这是我的自定义PropertyEditor

public class CustomResourceArrayPropertyEditor extends ResourceArrayPropertyEditor
{
  private final ResourcePatternResolver resourcePatternResolver;
  public CustomResourceArrayPropertyEditor()
  {
    this(new PathMatchingResourcePatternResolver());
  }
  public CustomResourceArrayPropertyEditor(ResourcePatternResolver resourcePatternResolver)
  {
    super(resourcePatternResolver, null);
    this.resourcePatternResolver = resourcePatternResolver; 
  }
  @Override
  public void setAsText(String text)
  {
    String pattern = resolvePath(text).trim();
    String[] resourceNames = StringUtils.commaDelimitedListToStringArray(pattern);
    List<Resource> resourceList = new ArrayList<Resource>();
    try {
      for (String resourceName: resourceNames)
      {
        Resource[] resources = resourcePatternResolver.getResources(resourceName);
        for (Resource res: resources)
          resourceList.add(res);
      }
    }
    catch (IOException ex) {
      throw new IllegalArgumentException("Could not resolve resource location pattern [" + pattern + "]", ex);
    }
    setValue(resourceList.toArray(new Resource[0]));
  }
}

我能想到的另一个解决方法是创建一个BeanFactoryPostProcessor来访问bean并更新util:propertiescontext:propery-placeholder的BEAN定义,以简单地将TypedStringValue用于locations属性,而不是String[]

。 。

希望它有帮助。

相关内容