Spring 有一个非常方便的名为PropertyPlaceholderConfigurer的类,它采用标准的 .properties 文件并将其中的值注入到您的 bean.xml 配置中。
有谁知道一个做完全相同的事情的类,并以相同的方式与 Spring 集成,但接受 XML 文件进行配置。具体来说,我正在考虑 Apache 消化器风格的配置文件。这样做很容易,我只是想知道是否有人已经拥有。
建议?
Spring 有一个非常方便的名为PropertyPlaceholderConfigurer的类,它采用标准的 .properties 文件并将其中的值注入到您的 bean.xml 配置中。
有谁知道一个做完全相同的事情的类,并以相同的方式与 Spring 集成,但接受 XML 文件进行配置。具体来说,我正在考虑 Apache 消化器风格的配置文件。这样做很容易,我只是想知道是否有人已经拥有。
建议?
我刚刚对此进行了测试,它应该可以正常工作。
PropertiesPlaceholderConfigurer 包含一个 setPropertiesPersister 方法,因此您可以使用自己的PropertiesPersister子类。默认的 PropertiesPersister 已经支持 XML 格式的属性。
只是为了向您展示完整的工作代码:
JUnit 4.4 测试用例:
package org.nkl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration(locations = { "classpath:/org/nkl/test-config.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class PropertyTest {
@Autowired
private Bean bean;
@Test
public void testPropertyPlaceholderConfigurer() {
assertNotNull(bean);
assertEquals("fred", bean.getName());
}
}
弹簧配置文件test-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
">
<context:property-placeholder
location="classpath:/org/nkl/properties.xml" />
<bean id="bean" class="org.nkl.Bean">
<property name="name" value="${org.nkl.name}" />
</bean>
</beans>
XML 属性文件properties.xml
- 有关使用说明,请参见此处。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="org.nkl.name">fred</entry>
</properties>
最后是 bean:
package org.nkl;
public class Bean {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
希望这可以帮助...
发现 Spring Modules 提供了 Spring 和 Commons Configuration 之间的集成,它具有层次结构的 XML 配置样式。这直接与 PropertyPlaceholderConfigurer 相关联,这正是我想要的。
一直试图自己想出一个很好的解决方案
我想出的内容如下,抱歉,这很啰嗦,但我喜欢它作为一种解决方案,因为我相信它涵盖了所有内容。希望这可能对某人有用。先说些琐碎的:
我希望将属性值注入的 bean:
package com.ndg.xmlpropertyinjectionexample;
public final class MyBean
{
private String firstMessage;
private String secondMessage;
public final String getFirstMessage ()
{
return firstMessage;
}
public final void setFirstMessage (String firstMessage)
{
this.firstMessage = firstMessage;
}
public final String getSecondMessage ()
{
return secondMessage;
}
public final void setSecondMessage (String secondMessage)
{
this.secondMessage = secondMessage;
}
}
测试类以创建上述 bean 并转储它获得的属性值:
package com.ndg.xmlpropertyinjectionexample;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Main
{
public final static void main (String [] args)
{
try
{
final ApplicationContext ctx = new ClassPathXmlApplicationContext ("spring-beans.xml");
final MyBean bean = (MyBean) ctx.getBean ("myBean");
System.out.println (bean.getFirstMessage ());
System.out.println (bean.getSecondMessage ());
}
catch (final Exception e)
{
e.printStackTrace ();
}
}
}
MyConfig.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:myconfig="http://ndg.com/xmlpropertyinjectionexample/config" targetNamespace="http://ndg.com/xmlpropertyinjectionexample/config">
<xsd:element name="myConfig">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="someConfigValue" type="xsd:normalizedString" />
<xsd:element minOccurs="1" maxOccurs="1" name="someOtherConfigValue" type="xsd:normalizedString" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
基于 XSD 的示例 MyConfig.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<config:myConfig xmlns:config="http://ndg.com/xmlpropertyinjectionexample/config">
<someConfigValue>First value from XML file</someConfigValue>
<someOtherConfigValue>Second value from XML file</someOtherConfigValue>
</config:myConfig>
运行 xsd2java 的 pom.xml 文件的片段(除了设置为 Java 1.6 和 spring-context 依赖项之外,这里没有太多其他内容):
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<id>main-xjc-generate</id>
<phase>generate-sources</phase>
<goals><goal>generate</goal></goals>
</execution>
</executions>
</plugin>
现在是 spring XML 本身。这将创建一个模式/验证器,然后使用 JAXB 创建一个解组器以从 XML 文件创建一个 POJO,然后使用 spring # 注释通过查询 POJO 来注入属性值:
<?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.2.xsd" >
<!-- Set up schema to validate the XML -->
<bean id="schemaFactory" class="javax.xml.validation.SchemaFactory" factory-method="newInstance">
<constructor-arg value="http://www.w3.org/2001/XMLSchema"/>
</bean>
<bean id="configSchema" class="javax.xml.validation.Schema" factory-bean="schemaFactory" factory-method="newSchema">
<constructor-arg value="MyConfig.xsd"/>
</bean>
<!-- Load config XML -->
<bean id="configJaxbContext" class="javax.xml.bind.JAXBContext" factory-method="newInstance">
<constructor-arg>
<list>
<value>com.ndg.xmlpropertyinjectionexample.config.MyConfig</value>
</list>
</constructor-arg>
</bean>
<bean id="configUnmarshaller" class="javax.xml.bind.Unmarshaller" factory-bean="configJaxbContext" factory-method="createUnmarshaller">
<property name="schema" ref="configSchema" />
</bean>
<bean id="myConfig" class="com.ndg.xmlpropertyinjectionexample.config.MyConfig" factory-bean="configUnmarshaller" factory-method="unmarshal">
<constructor-arg value="MyConfig.xml" />
</bean>
<!-- Example bean that we want config properties injected into -->
<bean id="myBean" class="com.ndg.xmlpropertyinjectionexample.MyBean">
<property name="firstMessage" value="#{myConfig.someConfigValue}" />
<property name="secondMessage" value="#{myConfig.someOtherConfigValue}" />
</bean>
</beans>
我不确定 Apache 消化器风格的配置文件,但我找到了一个不难实现且适合我的 xml 配置文件的解决方案。
您可以使用 spring 中的普通 PropertyPlaceholderConfigurer,但要读取您的自定义配置,您必须创建自己的 PropertiesPersister,您可以在其中解析 xml(使用 XPath)并自己设置所需的属性。
这是一个小例子:
首先通过扩展默认的 PropertiesPersister 创建你自己的:
public class CustomXMLPropertiesPersister extends DefaultPropertiesPersister {
private XPath dbPath;
private XPath dbName;
private XPath dbUsername;
private XPath dbPassword;
public CustomXMLPropertiesPersister() throws JDOMException {
super();
dbPath = XPath.newInstance("//Configuration/Database/Path");
dbName = XPath.newInstance("//Configuration/Database/Filename");
dbUsername = XPath.newInstance("//Configuration/Database/User");
dbPassword = XPath.newInstance("//Configuration/Database/Password");
}
public void loadFromXml(Properties props, InputStream is)
{
Element rootElem = inputStreamToElement(is);
String path = "";
String name = "";
String user = "";
String password = "";
try
{
path = ((Element) dbPath.selectSingleNode(rootElem)).getValue();
name = ((Element) dbName.selectSingleNode(rootElem)).getValue();
user = ((Element) dbUsername.selectSingleNode(rootElem)).getValue();
password = ((Element) dbPassword.selectSingleNode(rootElem)).getValue();
}
catch (JDOMException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
props.setProperty("db.path", path);
props.setProperty("db.name", name);
props.setProperty("db.user", user);
props.setProperty("db.password", password);
}
public Element inputStreamToElement(InputStream is)
{
...
}
public void storeToXml(Properties props, OutputStream os, String header)
{
...
}
}
然后将 CustomPropertiesPersister 注入应用程序上下文中的 PropertyPlaceholderConfigurer:
<beans ...>
<bean id="customXMLPropertiesPersister" class="some.package.CustomXMLPropertiesPersister" />
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
<property name="location" value="file:/location/of/the/config/file" />
<property name="propertiesPersister" ref="customXMLPropertiesPersister" />
</bean>
</beans>
之后,您可以像这样使用您的属性:
<bean id="someid" class="some.example.class">
<property name="someValue" value="$(db.name)" />
</bean>