可扩展XML-Schema机制
扩展流程

实例
XSD文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.demo.com/schema/people" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.demo.com/schema/people" elementFormDefault="qualified"> <xsd:import namespace="http://www.springframework.org/schema/beans" /> <xsd:element name="people"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="name" type="xsd:string"/> <xsd:attribute name="age" type="xsd:int"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
|
配置文件
实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class People { private String id; private String name; private Integer age; public People() {} @Override public String toString() { return "People{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", age=" + age + '}'; } 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; } }
|
NameSpaceHandler
1 2 3 4 5 6 7
| import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class MySchemaNameSpaceHandler extends NamespaceHandlerSupport{ @Override public void init() { registerBeanDefinitionParser("people", new PeopleBeanDefinitionParser(People.class)); } }
|
BeanDefinitionParser
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; public class PeopleBeanDefinitionParser implements BeanDefinitionParser {
private final Class<?> beanClass;
public PeopleBeanDefinitionParser(Class<?> beanClass) { this.beanClass = beanClass; }
@Override public BeanDefinition parse(Element element, ParserContext parserContext) { String name = element.getAttribute("name"); String age = element.getAttribute("age"); String id = element.getAttribute("id"); RootBeanDefinition beanDefinition = new RootBeanDefinition(); beanDefinition.setBeanClass(beanClass); beanDefinition.setLazyInit(false); if (null != id) { beanDefinition.getPropertyValues().add("id", id); } if (null != name) { beanDefinition.getPropertyValues().add("name", name); } if (null != age) { beanDefinition.getPropertyValues().add("age", age); } parserContext.getRegistry().registerBeanDefinition("people", beanDefinition); return beanDefinition; } }
|
目录结构
1 2 3 4 5 6 7 8 9 10 11
| src -- com.dist.schema -- People.java -- MySchemaNameSpaceHandler.java -- PeopleBeanDefinitionParser.java resources -- META-INF -- people.xsd -- spring.handlers -- spring.schemas -- spring.xml
|
XML信息
1 2 3 4 5 6 7 8 9 10 11
| <?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:people="http://www.demo.com/schema/people" xsi:schemaLocation=" http://www.demo.com/schema/people http://www.demo.com/schema/people/people.xsd">
<people:people id="people" name="wansw" age="123"/>
</beans>
|
测试类
1 2 3 4 5 6 7 8 9
| @Test public void testXML() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-mvc.xml"); People people = (People)context.getBean("people"); System.out.println(people.toString()); }
|
执行过程
在Spring解析XML,遇到自定义Element时,调用 parseCustomElement 方法:
1 2 3 4 5 6 7 8 9
| public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { String namespaceUri = getNamespaceURI(ele); NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { return null; } return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Override public NamespaceHandler resolve(String namespaceUri) { Map<String, Object> handlerMappings = getHandlerMappings(); Object handlerOrClassName = handlerMappings.get(namespaceUri); if (handlerOrClassName == null) { return null; } else if (handlerOrClassName instanceof NamespaceHandler) { return (NamespaceHandler) handlerOrClassName; } else { String className = (String) handlerOrClassName; try { Class<?> handlerClass = ClassUtils.forName(className, this.classLoader); if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) { throw new FatalBeanException(); } NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass); namespaceHandler.init(); handlerMappings.put(namespaceUri, namespaceHandler); return namespaceHandler; } } }
|