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

2019-01-28  本文已影响0人  cjxz

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

demo

文件内容

<?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文件的方式解析

http\://xxx.xxx.com/schema/myns=com.spring.start.namespace.MynsNameSpaceHandler
<?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>
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

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;
    }
}
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提供给我们使用的抽象类

上一篇下一篇

猜你喜欢

热点阅读