2017-03-10 84 views
0

我們需要一起加載多個屬性文件,並將它們用作屬性的一個來源。 <util:properties>允許您傳遞逗號分隔的文件列表,並且一切正常。所以,以下是很好的:當文件列表是參數時,使用Spring <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。

我在想什麼時候Spring試圖用逗號分割這些文件,它看起來像在解析$ {allPropertiesFiles}之前發生的。例如,如果我按照以下方式執行,它可以正常工作,但對於我們來說這不是一個實際的解決方案,因爲我們不知道該列表中包含多少個文件。

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

UPDATE:

似乎在${...}解決屬性值前是一個春天的問題與處理和分離與「」。我甚至嘗試過使用Spring EL來分割它,但是它再次解析有效的EL失敗,因爲它首先基於''分解它,然後評估表達式。以下示例在EL解析異常時失敗:

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

僅供參考此觀察結果與Spring 4.2.x.任何建議,非常感謝。

回答

0

於是,我找到了一個解決方案/解決方法,我的問題,並想在這裏分享。

util:propertiescontext:property-placeholder bean的解析器通過,location財產分割給定的字符串值。它發生在屬性分辨率發生之前。因此,如果您想將屬性文件的逗號分隔列表傳遞給這些bean,它將不起作用。

因此,我決定直接使用PropertiesFactoryBean,而不是使用<util:properties>,並將位置設置爲參數。這解決了Spring定義是如何在Spring中構建的,因爲它使用Spring的默認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訪問豆類和更新豆的定義util:propertiescontext:propery-placeholder只需使用TypedStringValue代替locations財產而不是String[]

希望它有幫助。

0

您是否嘗試過用雙引號括起變量值? 在一個小的測試,這個工作就像一個魅力:

的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}] 
+0

您需要雙引號,因爲您將屬性文件列表作爲jvm參數傳遞,並且列表中逗號後面有一個空格。我的列表來自另一個屬性文件,如果我用「」包圍它,它將成爲屬性值的一部分。 – user3739116

+0

其次,我試過你的例子,它只適用於我,如果列表作爲jvm arg與Spring 4.3.x傳遞。由於列表中的逗號,Spring的早期版本(例如4.2.x)仍然失敗。我們現在在Spring 4.2.x上,目前無法升級。第三,當我嘗試從由<'加載的屬性文件傳遞列表時,您的示例失敗。它看起來像Spring 4.3.x更好地處理jvm arg,不知道爲什麼。如果我錯了,請讓我知道。 – user3739116

相關問題