spring自定义标签

 

整体思路:

  • 创建一个需要扩展的组件
  • 定义一个XSD文件,描述组件内容
  • 创建一个java类,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义
  • 创建一个Handler类,扩展子NameSpaceHandlerSupport,目的是将组件注册到容器。
  • 编写(添加)Spring.handlers和Spring.schemas文件。

解析流程:通过Spring.schemas找到对应的XSD文件,校验xml格式;通过Spring.handlers找到对应的NamespaceHandler类作为解析自定义标签的类,通过init方法中的参数BeanDefinition实现类,根据解析的值生成BeanDefinition,

目录结构

创建模型类

public class Apple {
    private String name;
    private String appleColor;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAppleColor() {
        return appleColor;
    }
    public void setAppleColor(String appleColor) {
        this.appleColor = appleColor;
    }
}

创建xsd文件

对于该类标签的定义,spring中有着相应的XSD定义文档
http://www.springframework.org/schema/beans
对于XSD,简单的说是xml的一个标签的定义,在这里就不对XSD过多的解释了,祥见
http://www.w3school.com.cn/schema/schema_example.asp

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.zyx.com/schema/apple"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:beans="http://www.springframework.org/schema/beans"
            targetNamespace="http://www.zyx.com/schema/apple"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified">
    <xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans.xsd" />
    <xsd:element name="apple">
        <xsd:complexType>
            <xsd:all>
                <xsd:element ref="apple-color" minOccurs="1" maxOccurs="1"/>
            </xsd:all>
            <xsd:attribute name="id" type="xsd:string" />
            <xsd:attribute name="name" type="xsd:string" use="required"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="apple-color">
        <xsd:complexType>
            <xsd:attribute name="color" type="xsd:string" use="required"/>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

type是用来定义该属性的格式,例如
xsd:string 表示是一个字符串,对格式没什么要求
xsd:id 表示该属性的值是一个id,有格式要求(例如不能以数字开头)。
xsd:IDREF 表示该属性的值与某xsd:id属性的值对应
其他还有很多,例如number,double,datetime等等。

编写spring.schemas

改配置文件主要是用一个url来映射我们第一步配置好的文件,形式如下

http\://www.zyx.com/schema/apple.xsd=META-INF/namespace/apple.xsd

编写BeanDefinition,解析xml

public class AppleBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

    protected Class getBeanClass(Element element) {
        return Apple.class;
    }

    protected void doParse(Element element, BeanDefinitionBuilder bean) {
        String name = element.getAttribute("name");
        String color = parseAppleColor(element);

        if (StringUtils.hasText(name)) {
            bean.addPropertyValue("name", name);
        }
        if (StringUtils.hasText(color)) {
            bean.addPropertyValue("appleColor", color);
        }
    }

    private String parseAppleColor(Element element) {
        Element colorElement = DomUtils.getChildElementByTagName(element, "apple-color");
        return colorElement.getAttribute("color");
    }
}

编写NamespaceHandlerSupport

我们配置了com.zyx.demo.springNamespace.AppleNamespaceHandler类作为解析自定义标签的类,所以namespace为apple的标签,都会用这里注册的标签解析器来解析

public class AppleNamespaceHandler extends NamespaceHandlerSupport {
    public void init() {
        registerBeanDefinitionParser("apple",new AppleBeanDefinitionParser());
    }
}

编写spring.handlers

这个配置文件用来配置解析我们apple标签,然后生成一些BeanDefinition进行注册

http\://www.zyx.com/schema/apple=com.zyx.demo.springNamespace.AppleNamespaceHandler

 

到这里就写完了,下面是测试

测试:创建spring.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:myname="http://www.zyx.com/schema/apple"
       xsi:schemaLocation="
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
     http://www.zyx.com/schema/apple http://www.zyx.com/schema/apple.xsd"
       default-autowire="byName">

    <myname:apple id="xxx"  name="hongfushi">
        <myname:apple-color color="red"></myname:apple-color>
    </myname:apple>

</beans>

测试代码

@Controller
@RequestMapping("/test")
public class TestSpringNamespace {

    @ResponseBody
    @RequestMapping("spring/namespace")
    public String test(){
        Apple apple = SpringUtils.getBean(Apple.class);
        System.out.println(apple.toString());
        return apple.toString();
    }
}

 

posted @ 2018-02-02 18:17  qq871928901  阅读(321)  评论(0编辑  收藏  举报