Spring的自定義標籤

當Spring拿到一個元素時首先要作的是根據命名空間進行解析,若是是默認的命名空間,則使用parseDefaultElement方法進行元素解析,不然使用parseCustom Element方法進行解析。node

    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (node instanceof Element) {
                    Element ele = (Element) node;
                    if (delegate.isDefaultNamespace(ele)) {
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }

    public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
        String namespaceUri = getNamespaceURI(ele);
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
        if (handler == null) {
            error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
            return null;
        }
        return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    }

自定義標籤的使用

擴展Spring自定義標籤配置大體須要如下幾個步驟(前提是要把Spring的Core包加入項目中)。spring

  1. 建立一個須要擴展的組件。
  2. 定義一個XSD文件描述組件內容。
  3. 建立一個文件,實現BeanDefinitionParser接口,用來解析XSD文件中的定義和組件定義。
  4. 建立一個Handler文件,擴展自NamespaceHandlerSupport,目的是將組件註冊到Spring容器。
  5. 編寫Spring.handlers和Spring.schemas文件。

如今咱們就按照上面的步驟一步步地體驗自定義標籤的過程。dom

第一步:ide

public class TestBean {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "TestBean{" +
                "name='" + name + '\'' +
                '}';
    }
}

第二步:this

<?xml version="1.0" encoding="UTF-8" standalone="no"?>  
<xsd:schema xmlns="http://code.alibabatech.com/schema/dubbo"  
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"   
        targetNamespace="http://code.alibabatech.com/schema/dubbo">  
  
        <xsd:element name="custom" type="customType">  
        </xsd:element>  
        <xsd:complexType name="customType">  
                <xsd:attribute name="id" type="xsd:ID">  
                </xsd:attribute>  
                <xsd:attribute name="name" type="xsd:string">  
                </xsd:attribute>  
        </xsd:complexType>  
  
</xsd:schema> 

第三步:spa

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 TestCustomBeanDefinitionParser implements BeanDefinitionParser {  
  
    public BeanDefinition parse(Element element, ParserContext parserContext) {  
  
        String id = element.getAttribute("id");  
        String name = element.getAttribute("name");  
  
        RootBeanDefinition beanDefinition = new RootBeanDefinition();  
        beanDefinition.setBeanClass(TestBean.class);  
        beanDefinition.getPropertyValues().addPropertyValue("name", name);  
        parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);  
  
        return beanDefinition;  
    }  
}  

第四步:code

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;  
public class TestNamespaceHandler extends NamespaceHandlerSupport {  
    public void init() {  
        registerBeanDefinitionParser("custom", new TestCustomBeanDefinitionParser());  
    }  
}  

第五步:xml

spring.handlers:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
spring.schemas:
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsdblog

第六步:接口

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"  
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">  
          
        <dubbo:custom id="testCustom" name="this is a test custom tag" />  
</beans>  

import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
public class Main {  
  
    public static void main(String[] args) {  
        String xml = "classpath:test.xml";  
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { xml });  
        System.out.println(context.getBean("testCustom"));  
    }  
}  

上例輸出爲:
TestBean {name=this is a test custom tag}
相關文章
相關標籤/搜索