spring自定义xml配置标签

在开发中经常用到xml配置,而在配置文件中可以使用各种各样的xml节点名称。其中典型的就是dubbo源代码中定义了各种标签。在dubbo官网上还可以看到xml配置的消费者bean对象,服务提供者等,在这些配置中会指定接口类名,指定id,group, version等等信息。

自定义标签需要做哪些动作呢

1、自定标签限制文件, 资源文件resources/xiaoming-1.0.xsd

  • 这个限制文件指定了标签的结构
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schema xmlns="http://zhangweiblog.cn/schema/xiaoming"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://zhangweiblog.cn/schema/xiaoming"
    elementFormDefault="qualified">
    <!-- 定义student顶层标签,其类型是复杂类型Student -->
    <xsd:element name="student" type="Student">
    <xsd:annotation>
    <xsd:documentation><![CDATA[ The student info ]]></xsd:documentation>
    </xsd:annotation>
    </xsd:element>

    <!-- 定义Student类型可以有哪些属性 -->
    <xsd:complexType name="Student">
    <xsd:attribute name="id" type="xsd:string">
    <xsd:annotation>
    <xsd:documentation><![CDATA[ The unique identifier for a bean. ]]></xsd:documentation>
    </xsd:annotation>
    </xsd:attribute>
    <xsd:attribute name="name" type="xsd:string">
    <xsd:annotation>
    <xsd:documentation><![CDATA[ The name of the bean. ]]></xsd:documentation>
    </xsd:annotation>
    </xsd:attribute>
    </xsd:complexType>
    </xsd:schema>

2、在其它配置文件中指定命名空间

  • 注意标签xiaoming:这个写方式是xmlns:xiaoming=”http://zhangweiblog.cn/schema/xiaoming“ 决定的,这里的xmlns:xiaoming改成xmlns:xiao下面就需要改成对应xiao, 如果你的ide是idea,那么你可以看到明显的报错信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xiaoming="http://zhangweiblog.cn/schema/xiaoming"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://zhangweiblog.cn/schema/xiaoming
    http://zhangweiblog.cn/schema/xiaoming/xiaoming-1.0.xsd">

    <xiaoming:student id="xiaoming" name="小明"/>
    </beans>

3、标签xml解析类

  • 这个解析类决定了,当解析到xiaoming:student这个标签时候,代码需要做的动作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    package com.zw.dubbo.xsd;

    import com.zw.dubbo.factorybean.Student;
    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;

    public class XiaomingDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
    System.out.println("开始解析了");
    RootBeanDefinition bd = new RootBeanDefinition();
    // 不延迟加载
    bd.setLazyInit(false);
    String id = element.getAttribute("id");
    String name = element.getAttribute("name");
    bd.setBeanClass(Student.class);
    MutablePropertyValues propertyValues = bd.getPropertyValues();
    propertyValues.addPropertyValue("name", name);
    // 注入一个bean对象
    parserContext.getRegistry().registerBeanDefinition("student", bd);
    return bd;
    }
    }

4、编写命名空间处理类

  • 这里是这个标签的解析的源头,决定了哪个标签使用哪个解析类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.zw.dubbo.xsd;

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

    public class XiaomingNamespaceHandler extends NamespaceHandlerSupport {

    @Override
    public void init() {
    this.registerBeanDefinitionParser("student",
    new XiaomingDefinitionParser());
    }

    }

5、resources/META-INF/spring.schemas中添加配置

1
http\://zhangweiblog.cn/schema/xiaoming/xiaoming-1.0.xsd=./xiaoming-1.0.xsd

6、resources/META-INF/spring.handlers中指定命名空间处理类

1
http\://zhangweiblog.cn/schema/xiaoming=com.zw.dubbo.xsd.XiaomingNamespaceHandler

7、编写测试文件

  • 测试类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.zw.dubbo.xsd;

    import com.zw.dubbo.factorybean.Student;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class TestXsd {

    public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:xiaomingxsd.xml"});
    context.start();
    Student student = (Student) context.getBean("student");
    student.sayName();
    }
    }
  • 程序返回值
    1
    2
    3
    4
    5
    22:44:04.656 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@ea30797
    开始解析了
    22:44:05.025 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 1 bean definitions from class path resource [xiaomingxsd.xml]
    22:44:05.086 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'student'
    my name is 小明.