(转载)Spring自定义标签的原理

Spring自定义标签的原理

XML通常通过DTD、XSD定义,但DTD的表达能力较弱,XSD定义则能力比较强,能够定义类型,出现次数等。自定义标签需要XSD支持,在实现时使用Namespace扩展来支持自定义标签。

<bean id="beanId" class="com.xxx.xxxx.Xxxxx">
        <property name="property1">
            <value>XXXX</value>
        </property>
        <property name="property2">
            <value>XXXX</value>
        </property>
    </bean> 

当你在苦逼的写上面的代码时:

是不是会羡慕这样写代码呢?

<xxx:xxxx id="beanId"/>  

Xml代码

Spring通过XML解析程序将其解析为DOM树,通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDefinition。再通过Spring自身的功能对BeanDefinition实例化对象。

在期间,Spring还会加载两项资料:

  • META-INF/spring.handlers

    指定NamespaceHandler(实现org.springframework.beans.factory.xml.NamespaceHandler)接口,或使用org.springframework.beans.factory.xml.NamespaceHandlerSupport的子类。

  • META-INF/spring.schemas 

    在解析XML文件时将XSD重定向到本地文件,避免在解析XML文件时需要上网下载XSD文件。通过现实org.xml.sax.EntityResolver接口来实现该功能。

制作自定义的标签

spring.handlers:

Xml代码  

  1. http\://test.hatter.me/schema/test=me.hatter.test.TestNamespaceHandler

spring.schemas:

Xml代码  

  1. http\://test.hatter.me/schema/test/test.xsd=META-INF/test.xsd

test.xsd:

Xml代码  

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <xsd:schema xmlns="http://test.hatter.me/schema/test"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://test.hatter.me/schema/test">  

            <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>  

me.hatter.test.TestNamespaceHandler:

Java代码  

    package me.hatter.test;  

    import org.springframework.beans.factory.xml.NamespaceHandlerSupport;  

    public class TestNamespaceHandler extends NamespaceHandlerSupport {  

        public void init() {
            registerBeanDefinitionParser("custom", new TestCustomBeanDefinitionParser());
        }
    }  

me.hatter.test.TestCustomBeanDefinitionParser:

Java代码  

    package me.hatter.test;  

    import me.hatter.test.bean.TestBean;  

    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;
        }
    }  

测试代码

test.xml:

Xml代码  

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

me.hatter.test.main.Main:

Java代码  

    package me.hatter.test.main;  

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;  

    public class Main {  

        public static void main(String[] args) {
            String xml = "classpath:me/hatter/test/main/test.xml";
            ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { xml });
            System.out.println(context.getBean("testCustom"));
        }
    }  

上例输出为:

TestBean[name=thisis a test custom tag]
时间: 2024-10-02 22:17:24

(转载)Spring自定义标签的原理的相关文章

自己构建一个Spring自定义标签以及原理讲解

平时不论是在Spring配置文件中引入其他中间件(比如dubbo),还是使用切面时,都会用到自定义标签.那么配置文件中的自定义标签是如何发挥作用的,或者说程序是如何通过你添加的自定义标签实现相应的功能的呢?且看下文. 通过对本文的阅读,你会在阅读涉及到自定义标签的源码功能时事半功倍,而且还可以自己动手做出一个自己的自定义标签. 先呈上我自己在本地实现自定义标签的代码及对应讲解: 1.先无脑输出一个测试要用到的Bean类 1 public class User { 2 3 private Stri

Spring 自定义标签配置

前景:经常使用一些依赖于Spring的组件时,发现可以通过自定义配置Spring的标签来实现插件的注入,例如数据库源的配置,Mybatis的配置等.那么这些Spring标签是如何自定义配置的?学习Spring标签的自定义配置为以后实现分布式服务框架做技术储备. 技术分析:Spring的标签配置是通过XML来实现的,通过XSD(xml Schema Definition)来定义元素,属性,数据类型等. Spring自定义标签解析 1.Spring启动时通过扫描根目录下的META-INF文件下的sp

spring 自定义标签 学习

自定义配置文件到spring 中,有时候想做一些数据结构的配置化信息,根据业务做一个扩展. 首先: 在项目的META-INF目录下新建两个文件spring.handlers,和spring.shcemas Spring.handlers在类org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver中已经写死了要取mapping的handlerMappingsLocation的路径 public static fina

spring 自定义标签 学习二

在上篇中写的只支持写属性,不支持标签property的写法,但是如果有时候我们还想做成支持 property的用法,则可以在xsd中增加spring 自带的xsd引用 修改xsd文件如下: <?xml version="1.0"encoding="UTF-8"?> <xsd:schema xmlns="http://www.ruishenh.com/custom/myTest" xmlns:xsd="http://ww

Spring 自定义标签

Spring 工作流程是先加载解析xml配置文件:配置文件中存在默认的标签,也可以自定义标签.解析默认标签调用: 1 private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { 2 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { 3 importBeanDefinitionResource(ele); 4 } 5 else if

Spring自定义标签

一.原理: 1.Spring通过XML解析程序将其解析为DOM树, 2.通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDefinition. 3.再通过Spring自身的功能对BeanDefinition实例化对象. 二.自定义标签步骤 1.定义三个文件 META-INF/spring.handlers http\://www.newlandframework.com/dubbo=com.newlandframewor

dubbo源码学习(二) : spring 自定义标签

做dubbo的配置时很容易发现,dubbo有一套自己的标签,提供给开发者配置,其实每一个标签对应着一个 实体,在容器启动的时候,dubbo会对所有的配置进行解析然后将解析后的内容设置到实体里,最终dubbo会根据实体中的值生成贯穿全局的统一URL.利用自定义标签使配置简单明了化,与spring完美融合.下面自己写一个自定义标签,主要需要如下 几个步骤: 1.编写实体类2.编写Parser解析类3.编写NameSpaceHandle类4.配置spring.handlers5.配置spring.sc

Spring的自定义标签

当Spring拿到一个元素时首先要做的是根据命名空间进行解析,如果是默认的命名空间,则使用parseDefaultElement方法进行元素解析,否则使用parseCustom Element方法进行解析. protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl =

dubbo源码—dubbo自定义spring xml标签

dubbo为了和spring更好的集成,提供了一些xml配置标签,也就是自定义标签 spring自定义标签 spring自定义标签的方式如下: 设计配置属性和JavaBean 编写xsd文件,校验xml属性和便于编辑器提示 编写NamespaceHandler和BeanDefinitionParser解析xml对应的标签 编写spring.handlers和spring.schemas串联起所有部件,放在META_INF下面 在xml中引入对应的标签就可以使用 dubbo自定义标签 dubbo对