2013-02-07 41 views
9

我有一個屬性文件是這樣的:閱讀動態屬性映射到Spring管理的bean

my.properties file: 
app.One.id=1 
app.One.val=60 

app.Two.id=5 
app.Two.val=75 

和我讀到這些值代入我的豆地圖屬性在Spring配置文件是這樣的:

spring-config.xml: 
<bean id="myBean" class="myClass" scope="singleton"> 
    <property name="myMap"> 
     <map> 
      <entry key="${app.One.id}" value="${app.One.val}"/> 
      <entry key="${app.Two.id}" value="${app.Two.val}"/> 
     </map> 
    </property> 
</bean> 

這樣,如果我添加一個新的id/val到屬性文件中,我必須在config xml中添加一行以便在myMap中擁有新的id/val。

我的問題是,是否有一種方法可以在spring配置文件中指定key-val對,以便xml中定義的key-val數可以計算出屬性文件中的項目並創建映射。基本上我想在不同的環境中使用這個XML文件,我們在屬性文件中使用不同數量的鍵值項。我只是不想在每個環境中更改xml文件以讀取所有這些值。

讓我知道你是否需要任何其他細節。任何想法/意見表示讚賞。謝謝!

+0

您可以查看我的解決方案,謝謝。 – Vitaly

回答

7

這與春季EL和定製處理完成。

這對我來說是很有趣的嘗試。它的工作原理:)

的application.xml

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd 
    "> 

    <util:properties id="values" location="values.properties" /> 

    <bean id="hello" class="my.Hello"> 
     <property name="map" 
      value="#{T(my.Utils).propsToMap(values, '^(app\.\w*)\.id$', '{idGroup}.val')}" /> 
    </bean> 

</beans> 

Utils.java

package my; 

import java.util.Enumeration; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Properties; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class Utils { 

    public static Map<String, String> propsToMap(Properties props, 
      String idPatternString, String valuePatternString) { 

     Map<String, String> map = new HashMap<String, String>(); 

     Pattern idPattern = Pattern.compile(idPatternString); 

     for (Enumeration<?> en = props.propertyNames(); en.hasMoreElements();) { 
      String key = (String) en.nextElement(); 
      String mapKey = (String) props.getProperty(key); 

      if (mapKey != null) { 
       Matcher idMatcher = idPattern.matcher(key); 
       if (idMatcher.matches()) { 

        String valueName = valuePatternString.replace("{idGroup}", 
          idMatcher.group(1)); 
        String mapValue = props.getProperty(valueName); 

        if (mapValue != null) { 
         map.put(mapKey, mapValue); 
        } 
       } 
      } 
     } 

     return map; 
    } 
} 

Hello.java

package my; 

import java.util.Map; 

public class Hello { 

    private Map<String, String> map; 

    public Map<String, String> getMap() { 
     return map; 
    } 

    public void setMap(Map<String, String> map) { 
     this.map = map; 
    } 
} 

values.properties

app.One.id=1 
app.One.val=60 

app.Two.id=5 
app.Two.val=75 
1

這是一個經典的環境問題。

有兩種方法可以做到這一點:

  1. 在適當的屬性文件的末尾添加一個字符串的環境;在啓動時將該值傳遞給應用程序,並讓Spring選擇正確的值。
  2. 將這些動態屬性放入數據庫並在啓動時查詢它們。數據庫的JNDI將選擇正確的值。
+0

我們不想用DB來做到這一點。我正在尋找更像[Here]的東西(http://stackoverflow.com/questions/5274362/reading-a-dynamic-property-list-into-a-spring-managed-bean)。在那裏它更容易,因爲它只是一個列表,但我想知道是否有相當於用於地圖的東西? – kriver

+0

既然屬性是一個地圖,我不明白爲什麼不。嘗試一下。 – duffymo

0

我沒有找到解決此問題的理想方法,將動態地圖屬性讀入到彈簧配置信息中。使用數據庫也不是我們的選擇。這是我認爲是我們的最佳選擇:

  • 使用地圖鍵的標準格式/在屬性值對文件 如:KEY1 | val1,key2 | val2,key3 | val3,...,keyn | VALN

  • 閱讀本在配置Bean的字符串屬性或列表屬性喜歡這裏:Use String to List

  • 讓注入Java類拆分項目到地圖中的二傳手。

我打算將其標記爲答案。如果其他人有更好的方法來做到這一點,請註釋掉,我會改變它來回答。

4

也許我並沒有完全理解這裏的問題......
那麼簡化的方法呢?

my.properties file: 
1=60 
5=75 

應用上下文

<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="locations"> 
     <list> 
     <value>classpath: my.properties</value> 
     </list> 
    </property> 
</bean> 
<bean id="myClass" class="com.pakage.MyClass"> 
    <property name="myMap" ref=" myProperties"/> 
</bean> 

的Java Bean

public class MyClass { 
    private Map<String , String> myMap; 

    public void setMyMap(Map<String, String> myMap) { 
     this.myMap = myMap; 
    } 

    public Map<String , String> getMyMap(){ 
     return myMap; 
    } 
}