Reading a dynamic property map into Spring managed bean

后端 未结 4 2113
悲哀的现实
悲哀的现实 2021-02-05 23:53

I have a properties file like this:

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

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

And I read these values into a

相关标签:
4条回答
  • 2021-02-06 00:40

    I did not find an ideal way to solve this issue to have dynamic map property read into spring configuration info. Using DB was also not an option for us. This is what I found to be the best alternative for this:

    • Use a standard format for map key/value pair in the properties file eg: key1 | val1, key2 | val2, key3 | val3, ..., keyn | valn

    • Read this to a String property or List property in configuration bean like here: Use String to List

    • Let injected java class split the items into map in setter.

    I'm going to mark this as answer. If anyone else has better ways to do this, comment it out and I will change it to answer.

    0 讨论(0)
  • 2021-02-06 00:45

    It's a classic environment problem.

    There are two ways to do this:

    1. Add an environment string at the end of the appropriate .properties file; pass that value to the app when it starts and let Spring choose the correct one.
    2. Put those dynamic properties in a database and query for them on startup. The JNDI for the database will pick the right values.
    0 讨论(0)
  • 2021-02-06 00:47

    Maybe I did not fully understand the issue here...
    What about a simplified approach?

    my.properties file:
    1=60
    5=75
    

    Application Context

    <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;
        }
    }
    
    0 讨论(0)
  • 2021-02-06 00:56

    This is done with Spring EL and custom handling.

    It was just interesting for me to try it. It works :)

    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
    
    0 讨论(0)
提交回复
热议问题