Java 如何获取前缀为“abc”的所有属性。来自 PropertyPlaceholderConfigurer
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20796882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get all properties with prefix 'abc.' from PropertyPlaceholderConfigurer
提问by Freewind
In spring context file, I use org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
to load several configuration files:
在spring上下文文件中,我org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
用来加载几个配置文件:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>a.properties</value>
<value>b.properties</value>
<value>c.properties</value>
</list>
</property>
</bean>
The a.properties
, b.properties
, c.propertes
may have some hibernate configurations which have prefix of abc.
:
的a.properties
,b.properties
,c.propertes
可能具有的前缀一些休眠的配置abc.
:
abc.hibernate.show_sql=true
abc.hibernate.default_schema=myschema
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
abc.hibernate.xxx=xxx
Now I want to define a hibernate session factory:
现在我想定义一个休眠会话工厂:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<util:properties>
<prop key="hibernate.show_sql">${abc.hibernate.show_sql}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
</util:properties>
</property>
</bean>
You can see I have to write the property in bean declaration again and again:
你可以看到我必须一次又一次地在 bean 声明中写入属性:
<prop key="hibernate.xxx">${abc.hibernate.xxx}</prop>
Is there any way to just tell spring to get all properties which have prefix abc.
?
有什么方法可以告诉 spring 获取所有具有前缀的属性abc.
吗?
So I can write:
所以我可以写:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<something prefix="abc" /> <!-- TODO -->
</property>
</bean>
Is it possible or is there any other simple solutions for it?
是否有可能或是否有其他简单的解决方案?
回答by Vlad
You can use something like the following class to extend java.util.Properties:
您可以使用类似于以下类的内容来扩展 java.util.Properties:
import java.util.Enumeration;
import java.util.Properties;
public class PrefixedProperties extends Properties {
public PrefixedProperties(Properties props, String prefix){
if(props == null){
return;
}
Enumeration<String> en = (Enumeration<String>) props.propertyNames();
while(en.hasMoreElements()){
String propName = en.nextElement();
String propValue = props.getProperty(propName);
if(propName.startsWith(prefix)){
String key = propName.substring(prefix.length());
setProperty(key, propValue);
}
}
}
}
Then you can define sessionFactory as following:
然后你可以定义 sessionFactory 如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<bean id="sessionFactoryProperties" class="PrefixedProperties">
<constructor-arg ref="props"/> <!-- reference to all properties -->
<constructor-arg value="abc.hibernate."/> <!-- prefix -->
</bean>
</property>
</bean>
I don't see any other possibility to filter properties.
我看不到任何其他过滤属性的可能性。
回答by Sean Patrick Floyd
The PropertyPlaceHolderConfigurer
is a special construct that is meant for bean creation only. It does not expose the underlying properties in a way that you can access.
这PropertyPlaceHolderConfigurer
是一个特殊的构造,仅用于创建 bean。它不会以您可以访问的方式公开底层属性。
A possible workaround is to subclass PropertyPlaceHolderConfigurer
, as I have outlined in a previous answer of mine.
一种可能的解决方法是子类化PropertyPlaceHolderConfigurer
,正如我在我之前的回答中概述的那样。
Another way is to have a custom PropertiesFactoryBean, like this one:
另一种方法是使用自定义 PropertiesFactoryBean,如下所示:
public class PrefixedPropertyFactoryBean extends AbstractFactoryBean<Properties> {
private List<Resource> locations;
public void setLocations(List<Resource> locations) { this.locations = locations; }
private String prefix;
public void setPrefix(String prefix) { this.prefix = prefix; }
@Override public Class<?> getObjectType() { return Properties.class; }
@Override
protected Properties createInstance() throws Exception {
Properties properties = new Properties();
for (Resource resource : locations) {
properties.load( resource.getInputStream());
}
final Iterator<Object> keyIterator = properties.keySet().iterator();
while(keyIterator.hasNext()) {
if(!keyIterator.next().toString().startsWith(prefix))
keyIterator.remove();
}
return properties;
}
}
You can use this in your XML as follows:
您可以在您的 XML 中使用它,如下所示:
<bean id="hibernateProps" class="some.path.PrefixedPropertyFactoryBean">
<property name="locations">
<list>
<value>a.properties</value>
<value>b.properties</value>
<value>c.properties</value>
</list>
</property>
<property name="prefix" value="abc.hibernate" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties" ref="hibernateProps" />
</bean>
This is of course redundant, as you'd probably still have to wire the PropertyPlaceHolderConfigurer
to set up your other beans.
这当然是多余的,因为您可能仍然需要连接PropertyPlaceHolderConfigurer
来设置其他 bean。
回答by Jose Luis Martin
As Sean said, PropertyPlaceHolderConfigurer
don't expose his properties, but you could use reflection to filter them.
正如肖恩所说,PropertyPlaceHolderConfigurer
不要暴露他的属性,但你可以使用反射来过滤它们。
public static Properties filterProperties(String prefix, PropertyPlaceholderConfigurer ppc) {
Properties props = new Properties();
Method method = ReflectionUtils.findMethod(PropertiesLoaderSupport.class, "mergeProperties");
ReflectionUtils.makeAccessible(method);
Properties all = (Properties) ReflectionUtils.invokeMethod(method, ppc);
for (String key : all.stringPropertyNames()) {
if (key.startsWith(prefix))
props.setProperty(key, all.getProperty(key));
}
return props;
}
And inject with spel
并用拼写注入
<bean id="ppc" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
...
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties" value="#{T(SomeClass).filterProperties('abc.', @ppc)}" />
</bean>