美文网首页
04spring源码分析-spring自定义命名空间demo

04spring源码分析-spring自定义命名空间demo

作者: cjxz | 来源:发表于2019-01-28 18:02 被阅读0次

    有了前面一节XML Schema的文章支持,下面我们继续讨论spring是如何支持自定义命名空间的。spring支持自定义命名空间主要依赖NamespaceHandlerSupportBeanDefinitionParser两个抽象类来支持扩展的。我们先提供一个简单的demo来熟悉一下使用方法,然后再来分析两个类的作用。

    demo

    • 文件结构


      image.png

    文件内容

    • 自定义的XML schema
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <xsd:schema xmlns="http://xxx.xxx.com/schema/myns"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://xxx.xxx.com/schema/myns">
    
        <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
        <xsd:import namespace="http://www.springframework.org/schema/beans"/>
        <xsd:import namespace="http://www.springframework.org/schema/tool"/>
    
        <xsd:annotation>
            <xsd:documentation><![CDATA[ Namespace support for the myns test. ]]></xsd:documentation>
        </xsd:annotation>
    
        <xsd:complexType name="mybeanType">
            <xsd:attribute name="id" type="xsd:ID">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[ The unique identifier for a bean. ]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <xsd:attribute name="name" type="xsd:string" use="required">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[ The mybean name. ]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
            <xsd:attribute name="class" type="xsd:string" use="required">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[ The version. ]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:complexType>
        <xsd:element name="mybean" type="mybeanType">
            <xsd:annotation>
                <xsd:documentation><![CDATA[ The mybean config ]]></xsd:documentation>
            </xsd:annotation>
        </xsd:element>
    </xsd:schema>
    

    有了上面的xml schema即定义了一个元素mybean,稍后需要解析xml,按照当前这个xsd文件的方式解析

    • 指定谁处理xml schema(spring.handlers)
    http\://xxx.xxx.com/schema/myns=com.spring.start.namespace.MynsNameSpaceHandler
    
    • 使用自定义的命名空间(applicationContext-mynamespace.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:myns="http://xxx.xxx.com/schema/myns"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://xxx.xxx.com/schema/myns http://xxx.xxx.com/schema/myns.xsd
            ">
    
        <myns:mybean class="com.spring.start.namespace.People" id="mybean123" name="testMybean"></myns:mybean>
    
    </beans>
    
    • 处理命名空间的handler类
    package com.spring.start.namespace;
    
    import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
    
    /**
     * @Author: chao.zhu
     * @description:
     * @CreateDate: 2019/01/28
     * @Version: 1.0
     */
    public class MynsNameSpaceHandler extends NamespaceHandlerSupport {
        @Override
        public void init() {
            registerBeanDefinitionParser("mybean", new MybeanParser());
        }
    }
    

    上面的mybean就是我们定义的Element元素处理类使用我们自己的MybeanParser

    • xml解析类
    package com.spring.start.namespace;
    
    import org.springframework.beans.MutablePropertyValues;
    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;
    
    /**
     * @Author: chao.zhu
     * @description:
     * @CreateDate: 2019/01/28
     * @Version: 1.0
     */
    public class MybeanParser  implements BeanDefinitionParser {
    
        @Override
        public BeanDefinition parse(Element element, ParserContext parserContext) {
    
            RootBeanDefinition mbd =  new RootBeanDefinition();
            mbd.setBeanClassName(element.getAttribute("class"));
            String beanName = element.getAttribute("id");
            MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
            mutablePropertyValues.add("name", element.getAttribute("name"));
            mbd.setPropertyValues(mutablePropertyValues);
            parserContext.getRegistry().registerBeanDefinition(beanName, mbd);
    
            return mbd;
        }
    }
    
    • 需要实例的对象People
    package com.spring.start.namespace;
    
    /**
     * @Author: chao.zhu
     * @description:
     * @CreateDate: 2019/01/28
     * @Version: 1.0
     */
    public class People {
        private String name;
        private String id;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    }
    
    
    • 测试类
    package com.spring.start.namespace;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @Author: chao.zhu
     * @description:
     * @CreateDate: 2019/01/28
     * @Version: 1.0
     */
    public class MybeanNamespaceTest {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext-mynamespace.xml"},false);
            ac.setValidating(false);
            ac.refresh();
    
            People bean = ac.getBean("mybean123",People.class);
    
            System.out.println(bean.getName());
        }
    }
    

    下一节我们再来分析spring提供给我们使用的抽象类

    相关文章

      网友评论

          本文标题:04spring源码分析-spring自定义命名空间demo

          本文链接:https://www.haomeiwen.com/subject/uyfzjqtx.html