scheme扩展使用例子

1.引入pom依赖

  <properties>
        <springframework.version>4.3.16.RELEASE</springframework.version>
    </properties>
    <dependencies>
        <!-- **************************** Spring 依赖 **************************** -->
        <!-- 添加Spring-core包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <!-- 添加spring-tx包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <!-- 添加spring-context包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${springframework.version}</version>
        </dependency>
    </dependencies>

3.创建一个类 用于封装xml配置信息

public class DemoConfig {
    private String interfaceFullName;
    private String refName;

    public String getInterfaceFullName() {
        return interfaceFullName;
    }

    public void setInterfaceFullName(String interfaceFullName) {
        this.interfaceFullName = interfaceFullName;
    }

    public String getRefName() {
        return refName;
    }

    public void setRefName(String refName) {
        this.refName = refName;
    }
}

3.定义xsd 即xml配置规范

<?xml version="1.0" encoding="UTF-8"?>
<!--targetNamespace为命名空间 随便填 后面会使用-->
<xsd:schema xmlns="http://liqiang/schema/demo"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
            targetNamespace="http://liqiang/schema/demo" elementFormDefault="qualified"
            attributeFormDefault="unqualified">
    <xsd:import namespace="http://www.springframework.org/schema/beans" />
    <!--标签名字-->
    <xsd:element name="service">
        <xsd:complexType>
            <xsd:complexContent>
                <!--定义属性interface和ref 同时必填-->
                <xsd:extension base="beans:identifiedType">
                    <xsd:attribute name="interface" type="xsd:string" use="required"/>
                    <xsd:attribute name="ref" type="xsd:string" use="required" />
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>

4.创建sccema解析器

//定义自定义的scheme解析器 我们只需要解析标签信息将要创建对象的描述信息封装到beanDefinitionBuilder对象 spring容器会根据这些描述信息为我们创建对象对象
public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected Class getBeanClass(Element element) {
        return DemoConfig.class;
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder bean) {
        //获取interface值
        String interfaceFullName = element.getAttribute("interface");
        //获取ref值
        String refName = element.getAttribute("ref");
        if (refName!=null) {
            bean.addPropertyValue("interfaceFullName", interfaceFullName);
        }
        if (refName!=null) {
            bean.addPropertyValue("refName", refName);
        }
    }
}

5.注册类

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

/**
 * 注册自定义scheme解析器
 */
public class MyNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        //解析标签的名字  xsd <xsd:element name="service">配置
        registerBeanDefinitionParser("service", new SimpleDateFormatBeanDefinitionParser());
    }

6.resource目录创建META-INF子目录

7.META-INF创建文件spring.handlers并配置

http\://liqiang/schema/demo.xsd=demo.xsd

key=命名空间.xsd

value=xsd路径

8.META-INFO创建文件spring.handlers并配置

http\://liqiang/schema/demo=MyNamespaceHandler

key=命名空间

value=注册类的全名称

9.创建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:demo="http://liqiang/schema/demo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://liqiang/schema/demo http://liqiang/schema/demo.xsd">
    <demo:service id="test" interface="com.liqiang.userService" ref="userServiceImpl"/>

</beans>

10.运行demo

public class TestRun {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("demo.xml");
        DemoConfig dubboConfig = (DemoConfig) ctx.getBean("test");
        System.out.println(dubboConfig.getInterfaceFullName()+"|"+dubboConfig.getRefName());

    }
}

11.打印结果

02-14 03:33