1. 程式人生 > >spring自定義標簽

spring自定義標簽

handlers 字符 ons ns-3 接口 test urn 文件 ber

整體思路:

  • 創建一個需要擴展的組件
  • 定義一個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();
    }
}

spring自定義標簽