可以通过扩展Spring的Schema,来实现自定义配置。完成一个自定义配置一般需要完成下面的步骤:
下面是我测试的项目结构:
package cn.timd.spring.spring_schema;
public class Person {
private String id; //id默认是需要的
private String name;
private Integer age;
public Person() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://timd.cn/schema/person"
targetNamespace="http://timd.cn/schema/person"
xmlns:beans="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-4.3.xsd"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"></xsd:import>
<xsd:element name="person">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="name" type="xsd:string"></xsd:attribute>
<xsd:attribute name="age" type="xsd:int"></xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
关于xsd的详细信息,可查看:http://www.w3school.com.cn/schema/index.asp。
完成后,需要把xsd放到CLASSPATH下,一般都放在META-INF目录下。
NamespaceHandler类负责根据schema和节点找到相应的BeanDefinitionParser,然后由BeanDefinitionParser完成具体的解析工作。
因此需要分别完成NamespaceHandler和BeanDefinitionParser的实现类,Spring提供了默认实现类NamespaceHandlerSupport和AbstractSingleBeanDefinitionParser,简单的方式就是去继承这两个类。
package cn.timd.spring.spring_schema;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class PersonNamespaceHandler extends NamespaceHandlerSupport {
public void init(){
registerBeanDefinitionParser("person", new PersonBeanDefinitionParser());
}
}
registerBeanDefinitionParser用来把节点名和解析类关联起来
package cn.timd.spring.spring_schema;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
public class PersonBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
protected Class> getBeanClass(Element element) {
return Person.class;
}
protected void doParse(Element ele, BeanDefinitionBuilder bean) {
String id = ele.getAttribute("id");
String name = ele.getAttribute("name");
String age = ele.getAttribute("age");
if (StringUtils.hasText(id))
bean.addPropertyValue("id", Integer.valueOf(id));
if (StringUtils.hasText(name))
bean.addPropertyValue("name", name);
if (StringUtils.hasText(age))
bean.addPropertyValue("age", Integer.valueOf(age));
}
}
ele.getAttribute用于从配置中取得属性值,bean.addPropertyValue用于把属性值放到bean中
spring.handlers和spring.schemas用于串联所有的组件---xsd文件、NamespaceHandler类以及BeanDefinitionParser类。这两个文件必须放在META-INF下(xsd文件可以放在META-INF下,也可以放在类路径下)。
http\://timd.cn/schema/person=cn.timd.spring.spring_schema.PersonNamespaceHandler
http\://timd.cn/schema/person/person.xsd=META-INF/person.xsd
<?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:person="http://timd.cn/schema/person"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://timd.cn/schema/person
http://timd.cn/schema/person/person.xsd">
<person:person name="timchow" age="28" id="10086"></person:person>
</beans>
package cn.timd.spring.spring_schema;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("10086");
System.out.println(person);
}
}