【问题标题】:Reading a dynamic property map into Spring managed bean将动态属性映射读入 Spring 托管 bean
【发布时间】:2023-04-07 16:53:01
【问题描述】:

我有一个这样的属性文件:

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

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

然后我将这些值读入 Spring 配置文件中 bean 的 map 属性中,如下所示:

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 文件来读取所有这些值。

如果您需要任何其他详细信息,请告诉我。任何想法/cmets 表示赞赏。谢谢!

【问题讨论】:

  • 您能否查看我的解决方案,谢谢。

标签: java spring dynamic map javabeans


【解决方案1】:

这是一个经典的环境问题。

有两种方法可以做到这一点:

  1. 在相应的 .properties 文件末尾添加环境字符串;在应用启动时将该值传递给应用,让 Spring 选择正确的值。
  2. 将这些动态属性放入数据库并在启动时查询它们。数据库的 JNDI 将选择正确的值。

【讨论】:

  • 我们不想使用 DB 来做这件事。我正在寻找更像Here 的东西。因为它只是一个列表,所以更容易,但我想知道是否有与地图等效的东西?
  • 既然 Property IS-A Map,我不明白为什么不这样做。试试看。
【解决方案2】:

我没有找到解决此问题的理想方法,将动态地图属性读入弹簧配置信息。使用 DB 也不是我们的选择。这是我发现的最佳选择:

  • 在属性文件中使用标准格式的映射键/值对 例如:key1 |值 1,键 2 | val2,键 3 | val3, ..., 键 |值

  • 将其读取到配置 bean 中的 String 属性或 List 属性,如下所示:Use String to List

  • 让注入的java类在setter中将item拆分成map。

我将把它标记为答案。如果其他人有更好的方法来做到这一点,请将其注释掉,我会更改它来回答。

【讨论】:

    【解决方案3】:

    也许我没有完全理解这里的问题...
    那么简化的方法呢?

    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 豆

    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;
        }
    }
    

    【讨论】:

      【解决方案4】:

      这是通过 Spring 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
      

      【讨论】:

        猜你喜欢
        • 2011-07-13
        • 1970-01-01
        • 2021-04-02
        • 2020-08-24
        • 1970-01-01
        • 1970-01-01
        • 2014-05-27
        相关资源
        最近更新 更多