spring schema 扩展(NamespaceHandler,BeanDefinitionParser)

来源:互联网 发布:机器人单片机 编辑:程序博客网 时间:2024/05/19 03:26

前言:spring从2.0开始引入了一个新的机制用于扩展xml模式,我们就可以编写自定义的xml bean解析器然后集成到Spring IoC容器中(Spring不识别aop,mvc,这些标签都是通过本章要学习的内容,扩展标签

<mvc:interceptors></mvc:interceptors>
<aop:config></aop:config>


xml扩展大概有以下几个步骤:

  • 编写自定义类
  • 编写xml schema来描述自定义元素
  • 编写NamespaceHandler实现类
  • 编写BeanDefinitionParser实现类
  • 把以上组建注册到Spring

xml的schema约束:

先来说说xml文档的schema约束,它定义了xml文档的结构,内容和语法,包括元素和属性、关系的结构以及数据类型等等。有以下几点需要遵循:

1) 、所有的标签和属性都需要Schema来定义。(schema本身由w3c来定义)。

2)、所有的schema文件都需要以个ID,这里我们称之为 namespace,其值时一个url,通常是这个xml的xsd文件的地址。

3)、namespace值由 targetNamespace属性来指定

4)、引入一个schema约束,使用属性xmlns,属性值即为对应schema文件的命名空间 nameSpace。

5)、如果引入的schema非w3c组织定义的,必须指定schema文件的位置,schema文件的位置由 schemaLocation来指定。

6)、引入多个schema文件需要使用 别名。别名形式如下: xmlns:alias。

对于上述配置文件的详细解读:

1)、 声明默认的名称空间(xmlns="http://www.springframework.org/schema/beans")

2)、 声明XML Schema实例名称空间(http://www.w3.org/2001/XMLSchema-instance),并将xsi前缀与该名称空间绑定, 这样模式处理器就可以识别xsi:schemaLocation属性。XML Schema实例名称空间的前缀通常使用xsi

3)、 使 用xsi:schemaLocation属性指定名称空间(http://www.springframework.org/schema/beans) 和模式位置(http://www.springframework.org/schema/beans/spring-beans.xsd)相关。 XML Schema推荐标准中指出,xsi:schemaLocation属性可以在实例中的任何元素上使用,而不一定是根元素,不 过,xsi:schemaLocation属性必须出现在它要验证的任何元素和属性之前。

4)、使用别名引入多个schema文件。如上述 xmlns:mvc 、xmlns:tx 、xmlns:context等等。

编写自定义类

public class Miku {   private String name;   private int age;   private char sex;}

编写自定义schema,文件名应该为“miku.xsd”,路径为:classpath:META-INF/miku.xsd

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns="http://www.mycompany.com/schema/my"         xmlns:xsd="http://www.w3.org/2001/XMLSchema"         xmlns:beans="http://www.springframework.org/schema/beans"         targetNamespace="http://www.mycompany.com/schema/my"         elementFormDefault="qualified"         attributeFormDefault="unqualified"><xsd:import namespace="http://www.springframework.org/schema/beans"/><xsd:element name="miku">   <xsd:complexType>      <xsd:complexContent>         <xsd:extension base="beans:identifiedType">            <xsd:attribute name="name" type="xsd:string" use="required"/>            <xsd:attribute name="age" type="xsd:int"/>            <xsd:attribute name="sex" type="xsd:char"/>         </xsd:extension>      </xsd:complexContent>   </xsd:complexType></xsd:element></xsd:schema>



然后我们就可以像这样定义miku:
<miku :miku id="mymiku" name="hatsunemiku" age="16" sex="女"/>

编写NamespaceHandler

NamespaceHandler用于解析我们自定义名字空间下的所有元素,目前我们要解析上面的miku:miku元素。NamespaceHandler里面只有3个方法:

  • init()会在NamespaceHandler初始化的时候被调用。
  • BeanDefinition parse(Element, ParserContext) - 当Spring遇到一个顶层元素的时候被调用。
  • BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext) - 当Spring遇到一个属性或嵌套元素的时候调用.

Spring提供了默认实现类NamespaceHandlerSupport,我们只需在init的时候注册每个元素的解析器即可。

public class MikuNamespaceHandler extends NamespaceHandlerSupport {   @Override   public void init() {      //遇到miku元素的时候交给MikuBeanDefinitionParser来解析      registerBeanDefinitionParser("miku", new MikuBeanDefinitionParser());   }}

编写BeanDefinitionParser

当遇到miku元素时,Spring会交给MikuBeanDefinitionParser来解析。MikuBeanDefinitionParser取出相应的属性然后设置到bean中。

public class MikuBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {   @Override   protected Class<?> getBeanClass(Element element) {      //miku元素对应Miku对象类型      return Miku.class;   }   @Override   protected void doParse(Element element, BeanDefinitionBuilder builder) {      String name = element.getAttribute("name");      String age = element.getAttribute("age");      String sex = element.getAttribute("sex");      //把对应的属性设置到bean中      if(StringUtils.hasText(name))         builder.addPropertyValue("name", name);      if(StringUtils.hasText(age))         builder.addPropertyValue("age", age);      if(StringUtils.hasText(sex))         builder.addPropertyValue("sex", sex);   }}

注册handler和schema(将组件串联起来)

为了让Spring在解析xml的时候能够感知到我们的自定义元素,我们需要把namespaceHandler和xsd文件放到2个指定的配置文件中,这2个文件都位于META-INF目录中。

META-INF/spring.handlers

spring.handlers文件包含了xml schema uri和handler类的映射关系,比如:

http\://www.mycompany.com/schema/my=spring.xml.ext.schema.MikuNamespaceHandler

这表示遇到http\://www.mycompany.com/schema/my命名空间的时候会交给MikuNamespaceHandler来处理。

注意上面的冒号转义。 key部分必须和xsd文件中的targetNamespace值保持一致。

META-INF/spring.schemas

http\://www.mycompany.com/schema/miku.xsd=META-INF/miku.xsd

这样bean装载就完成了,写个测试开心的试一下吧~
转载请标明出处,本帖原创地址:http://blog.csdn.net/hatsune_miku_/article/details/77018869
阅读全文
0 0