如何使用Spring框架将属性文件中的值转换为Map?
现在我可以从财产文件注入值:如何使用Spring框架将属性文件中的值转换为Map?
@Value("${aaa.prop}")
public String someProp;
但我想更多的东西......
例如,我有一些属性文件:
aaa.props=p1,p2,p3
aaa.props.p1=qwe
aaa.props.p2=asd
aaa.props.p3=zxc
我知道当然,它包含属性aaa.props
,并且对其他属性一无所知。我想用这样的符号映射得到这个属性:
@Value ("${aaa.props}")
public Map<String, String> someProps;
所得someProps:{p1=qwe,p2=asd,p3=zxc}
恐怕你不能直接。但是你可以
- 执行
ApplicationContextAware
并将ApplicationContext
设置为您的bean中的字段。 - 在
@PostConstruct
方法调用context.getBean("${aaa.props}")
- 手工解析结果,并将其设置为所需的领域
有没有办法让所有物业找到我需要的物业? – 2012-10-12 10:38:43
好吧,我为你打造一个通用的方法:一个工厂bean,通过过滤其他地图创建一个地图(属性毕竟是一种地图)。
这里的工厂bean:
public class FilteredMapFactoryBean<V> extends
AbstractFactoryBean<Map<String, V>>{
private Map<String, V> input;
/**
* Set the input map.
*/
public void setInput(final Map<String, V> input){
this.input = input;
}
/**
* Set the string by which key prefixes will be filtered.
*/
public void setKeyFilterPrefix(final String keyFilterPrefix){
this.entryFilter = new EntryFilter<String, V>(){
@Override
public boolean accept(final Entry<String, V> entry){
return entry.getKey().startsWith(keyFilterPrefix);
}
};
}
public static interface EntryFilter<EK, EV> {
boolean accept(Map.Entry<EK, EV> entry);
}
/**
* If a prefix is not enough, you can supply a custom filter.
*/
public void setEntryFilter(final EntryFilter<String, V> entryFilter){
this.entryFilter = entryFilter;
}
private EntryFilter<String, V> entryFilter;
/**
* {@inheritDoc}
*/
@Override
public Class<?> getObjectType(){
return Map.class;
}
/**
* {@inheritDoc}
*/
@Override
protected Map<String, V> createInstance() throws Exception{
final Map<String, V> map = new LinkedHashMap<String, V>();
for(final Entry<String, V> entry : this.input.entrySet()){
if(this.entryFilter == null || this.entryFilter.accept(entry)){
map.put(entry.getKey(), entry.getValue());
}
}
return map;
}
}
这里是一个Spring bean定义文件的一些示例用法:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- use System.getProperties() as input -->
<bean class="spring.test.FilteredMapFactoryBean" id="javaMap">
<property name="keyFilterPrefix" value="java." />
<property name="input" value="#{T(java.lang.System).getProperties()}" />
</bean>
<!-- use custom properties as input -->
<bean class="spring.test.FilteredMapFactoryBean" id="customMap">
<property name="keyFilterPrefix" value="hello" />
<property name="input">
<props>
<prop key="hello">Is it me you're looking for?</prop>
<prop key="hello.again">Just called to say: hello.</prop>
<prop key="hello.goodby">You say goodbye and I say hello</prop>
<prop key="goodbye.blue.sky">Did-did-did-did-you hear the falling bombs?</prop>
<prop key="goodbye.ruby.tuesday">Who could hang a name on you?</prop>
</props>
</property>
</bean>
</beans>
,这里是一个测试类:
public class Tester{
@SuppressWarnings("unchecked")
public static void main(final String[] args){
final ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:spring/test/mapFactorybean.xml");
final Map<String, String> javaMap =
(Map<String, String>) context.getBean("javaMap");
print("java.", javaMap);
final Map<String, String> customMap =
(Map<String, String>) context.getBean("customMap");
print("hello.", customMap);
}
private static void print(final String prefix, final Map<String, String> map){
System.out.println("Map of items starting with " + prefix);
for(final Entry<String, String> entry : map.entrySet()){
System.out.println("\t" + entry.getKey() + ":" + entry.getValue());
}
System.out.println("");
}
}
的输出如预期:
Map of items starting with java.
java.runtime.name:Java(TM) SE Runtime Environment
java.vm.version:14.2-b01
java.vm.vendor:Sun Microsystems Inc.
java.vendor.url:http://java.sun.com/
java.vm.name:Java HotSpot(TM) Client VM
java.vm.specification.name:Java Virtual Machine Specification
java.runtime.version:1.6.0_16-b01
java.awt.graphicsenv:sun.awt.Win32GraphicsEnvironment
[... etc]
Map of items starting with hello.
hello.goodby:You say goodbye and I say hello
hello:Is it me you're looking for?
hello.again:Just called to say: hello.
'AbstractFactoryBean'默认为单例。在上下文中多次使用这个bean(具有不同的属性)不会是一个问题吗? – naXa 2014-09-24 13:25:03
@naXa这个答复是4岁。这些天FactoryBeans有点不赞成。我会用\ @Configuration类代替 – 2014-09-24 16:29:36
你可以做这样的事情: Maven的依赖
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
添加导入。
import javax.annotation.Resource;
...
@Resource (name="propertiesMapName")
public Properties someProps;
在Spring XML应用程序上下文:
<util:properties id="propertiesMapName" location="classpath:yourFile.properties"/>
你会需要这个命名空间
xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd
我可以知道为什么我在解决方案中有-1吗?这工作,我认为是一个非常干净的方式,我想明白什么是错的。谢谢 – cralfaro 2016-02-23 09:33:23
可以使用@Value
。
属性文件:
aaa.props={p1:'qwe',p2:'asd',p3:'zxc'}
Java代码:
@Value("#{${aaa.props}}")
private Map<String,String> someProps;
这是应该得到upvoted和接受作为答案。另外,那些使用基于Spring XML的配置的人可以简单地使用像'p:someProps =“#{$ {aaa.props}}”'这样的属性来注入。 – 2017-08-21 12:39:16
您可能会发现这个问题的答案非常有用:http://*.com/questions/9259819/how-to-read-值 - 从属性文件。将属性对象注入资源,解析列表1并相应地构建地图。 – mrembisz 2013-01-17 12:43:24