2012-06-21 33 views
3

引用的文件我的Spring配置如下:合併多個屬性由Spring

<jee:remote-slsb id="ejb1" 
    jndi-name="org.example.Ejb1" 
    business-interface="org.example.Ejb1" 
    environment-ref="ejb1Properties"> 
</jee:remote-slsb> 
<util:properties id="ejb1Properties" location="classpath:ejb1.properties"/> 

<jee:remote-slsb id="ejb2" 
    jndi-name="org.example.Ejb2" 
    business-interface="org.example.Ejb2" 
    environment-ref="ejb2Properties"> 
</jee:remote-slsb> 
<util:properties id="ejb2Properties" location="classpath:ejb2.properties"/> 

......因爲兩個EJB可以使用不同的JNDI的網址,不同的上下文工廠和認證證書。 ejb1.properties和ejb2.properties名稱相同的性能,具有不同的值:

ejb1.properties: 
    java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory 
    java.naming.provider.url=t3://example1:7101 
    java.naming.security.principal=id1 
    java.naming.security.credential=foo 

ejb2.properties: 
    java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory 
    java.naming.provider.url=t3://example2:7101 
    java.naming.security.principal=id2 
    java.naming.security.credential=bar 

不過,我想我的用戶有一個屬性文件來維護,而不是兩個。

顯然很容易寫,從一個核心特性文件生成ejb1.properties和ejb2.properties啓動腳本。但有沒有辦法讓Spring從單個文件獲取屬性,並正確地映射名稱?

+0

除非你以編程的方式做它,我想。 –

回答

5

據我所知,沒有什麼春天來處理你的情況。然而,一個直接的解決方案將是擴展PropertiesFactoryBean並重寫mergeProperties()方法。下面是過濾基於名稱前綴屬性條目這樣一個擴展的例子:

public class FilteringPropertiesFactoryBean extends PropertiesFactoryBean { 

    private String namePrefix; 

    @Override 
    protected Properties mergeProperties() throws IOException { 
     Properties unfilteredProperties = super.mergeProperties(); 

     Properties filteredProperties = new Properties(); 

     // iterator over keys 
     // discard entries whose key doesn't start with prefix 
     for (Object key : unfilteredProperties.keySet()) { 
      String name = key.toString(); 

      // trim the property name by removing the target prefix. 
      String trimmedName = trimName(name); 
      if (trimmedName != null) { 
       // add the property to the filtered collection 
       String value = unfilteredProperties.getProperty(name); 
       filteredProperties.setProperty(trimmedName, value); 
      } 
     } 

     return filteredProperties; 
    } 

    public void setNamePrefix(String value) { 
     this.namePrefix = value; 
    } 

    private String trimName(String name) { 
     // does name start with the prefix and is the name longer than the prefix 
     if (name.startsWith(namePrefix) && name.length() > namePrefix.length()) { 
      return name.substring(namePrefix.length()); 
     } 
     return null; 
    } 

} 

配置工廠bean會是這樣的:

<bean id="ejb1Properties" class="example.FilteringPropertiesFactoryBean"> 
    <property name="location" value="classpath:merged.properties"/> 
    <property name="namePrefix" value="ejb1."/> 
</bean> 

通過上述配置和merged.properties含的文件:

ejb1.java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory 
ejb1.java.naming.provider.url=t3://example1:7101 
ejb1.java.naming.security.principal=id1 
ejb1.java.naming.security.credential=foo 

ejb2.java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory 
ejb2.java.naming.provider.url=t3://example2:7101 
ejb2.java.naming.security.principal=id2 
ejb2.java.naming.security.credential=bar 

通過FilteringPropertiesFactoryBean#mergeProperties(返回的所得性質)是(注意前綴從最後一個屬性剝離名稱):

java.naming.factory.initial = weblogic.jndi.WLInitialContextFactory 
java.naming.provider.url = t3://example1:7101 
java.naming.security.principal = id1 
java.naming.security.credential = foo 
+0

我喜歡這種方法。謝謝。 – slim