Fellow Travellers

可扩展XML-Schema机制

万世威
字数统计: 734阅读时长: 4 min
2018/12/26 Share

可扩展XML-Schema机制

扩展流程

可扩展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
// META-INF/spring.handlers
http\://www.demo.com/schema/people=com.mvc.schema.MySchemaNameSpaceHandler

// META-INF/spring.schemas
http\://www.demo.com/schema/people/people.xsd=META-INF/people.xsd

实体类

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");
// 存放Bean信息的类
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);
}
// 注册到Spring容器中
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());
}
/**
People{id='people', name='wansw', age=123}
/

执行过程

在Spring解析XML,遇到自定义Element时,调用 parseCustomElement 方法:

1
2
3
4
5
6
7
8
9
// org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java
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);
// 执行 init 方法,调用NamespaceHandler(MySchemaNameSpaceHandler)的init方法
namespaceHandler.init();
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}
}
}
CATALOG
  1. 1. 可扩展XML-Schema机制
    1. 1.1. 扩展流程
    2. 1.2. 实例
      1. 1.2.1. XSD文件
      2. 1.2.2. 配置文件
      3. 1.2.3. 实体类
      4. 1.2.4. NameSpaceHandler
      5. 1.2.5. BeanDefinitionParser
    3. 1.3. 目录结构
      1. 1.3.1. XML信息
      2. 1.3.2. 测试类
    4. 1.4. 执行过程