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
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.
It's a classic environment problem.
There are two ways to do this:
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;
}
}
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