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 map property in my bean in Spring config file like this:
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>
This way if I add a new id/val to the properties file, I must add a row in config xml in order to have the new id/val in myMap.
My question is, is there a way to specify the key-val pairs in spring config file so that the number of key-vals defined in xml can figure out the items in the properties file and create a map. Basically I want to use this xml file in different environments where we use different number of key-value items in properties file. I just don't want to change the xml file in each environment to read in all these values.
Let me know if you need any other details. Any thoughts/comments is appreciated. Thanks!
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
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;
}
}
It's a classic environment problem.
There are two ways to do this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With