在spring中自定义xml标签并使用


前言

使用过spring+dubbo的朋友可能会有问,dubbo的xml标签(如:<dubbo:reference interface="cn.e3mall.content.service.ContentService" id="contentService" />)是怎么被spring解析并生成bean对象的?
想要了解dubbo和spring的融合,首先需要知道如何在spring中自定义xml标签。


一、总体步骤

  1. 设计javabean
  2. 编写XSD(XML Schema Definition)文件 ,定义XML语法规范,校验XML
  3. 编写NamespaceHandler和BeanDefinitionParser完成解析工作
  4. 编写spring.handler和spring.schemas串联所有部件
  5. 在spring配置文件中编写自定义xml标签
  6. 加载自定义xml标签的bean

二、具体案例

1.设计javabean

javabean代码如下(示例):

public class Person {

    private String name;
    private int age;

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.编写XSD(XML Schema Definition)约束文件

<xs:schema>元素中targetNamespace属性值和xmlns属性值是一样的
targetNamespace表示被此 schema 定义的元素所在的命名空间,xmlns表示默认的命名空间

代码如下(示例):

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.wgc.com/schema/wgc"     
           xmlns="http://www.wgc.com/schema/wgc"
           elementFormDefault="qualified">
    
    <xs:element name="person" type="personType"/>
    <xs:complexType name="personType">
        <xs:attribute name="id" type="xs:string" />
        <xs:attribute name="name" type="xs:string"/>
        <xs:attribute name="age" >
            <!--限定属性值在0~120之间-->
            <xs:simpleType>
                <xs:restriction base="xs:integer">
                    <xs:minInclusive value="0"/>
                    <xs:maxInclusive value="120"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
</xs:schema>

3、bean定义解析器:BeanDefinitionParser

自定义的BeanDefinitionParser需要实现BeanDefinitionParser接口的parse()方法,而我们继承的spring提供的抽象类AbstractSingleBeanDefinitionParser 已经实现了BeanDefinitionParser接口

public class WgcBeanDefinitionParser extends AbstractSingleBeanDefinitionParser  {

    @Override
    protected Class<?> getBeanClass(Element element) {
        return Person.class;
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {
        String name = element.getAttribute("name");
        int age = Integer.valueOf(element.getAttribute("age"));

        builder.addPropertyValue("name", name);
        builder.addPropertyValue("age", age);
    }

}

4、编写NamespaceHandler

我们自定义的类继承了spring提供的抽象类NamespaceHandlerSupport
registerBeanDefinitionParser()方法的参数"person"表示元素名称,也就是在xsd文件中定义的元素<xs:element name="person" type="personType"/>的name属性值

public class WgcNamespaceHandler extends NamespaceHandlerSupport {

    public void init() {
        registerBeanDefinitionParser("person", new WgcBeanDefinitionParser());
    }
}

5、 编写spring.handlers文件

1)此文件放在classpath下的META-INF文件夹下,内容以key=value的形式存放,意思是key代表的命名空间的元素使用value这个handler处理
2)key的值和xsd文件中targetNamespace的值相同,否则报错
3)value的值是我们自定义的NamespaceHandler的全限定性类名

http\://www.wgc.com/schema/wgc=com.wgc.custom.xml.schema.WgcNamespaceHandler

6、编写spring.schemas

1)此文件存放在classpath下的META-INF文件夹下,内容为key=value的形式
2)key值一般写为:xsd文件targetNamespace的值+xsd文件名称;如果不遵守此规则,那么应该让key的值和spring配置文件中xsi:schemaLocation中的value值相同,否则报错
3)value的值就是xsd文件的路径

http\://www.wgc.com/schema/wgc/wgc.xsd=META-INF/wgc.xsd

7、在spring配置文件中编写自定义的xml标签

1)xmlns:wgc="http://www.wgc.com/schema/wgc" 表示下面前缀使用 wgc:的元素和数据类型来自命名空间"http://www.wgc.com/schema/wgc",这个命名空间就是我们在XSD文件中定义的targetNamespace的值
2)xsi:schemaLocation的内容是成对存放的,例如:"http://www.wgc.com/schema/wgc" 表示需要使用的命名空间 ,它的值和xmlns:wgc的值相同,"http://www.wgc.com/schema/wgc/wgc.xsd" 表示命名空间使用的 xsd 的位置,这个地址和我们在spring.schemas文件中定义的一样

<?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:wgc="http://www.wgc.com/schema/wgc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.wgc.com/schema/wgc http://www.wgc.com/schema/wgc/wgc.xsd">

    <wgc:person id="person1" name="wgc" age="25" />

</beans>

8、编写启动类加载bean

public class CustomMainClass {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        Person person = (Person)ac.getBean("person1");
        System.err.println(person.toString());
    }
}

输出结果:

Person{name='wgc', age=25}

总结

今天只是写了如何在spring中自定义xml标签并使用,并未讲解其原理过程,等以后在进行分析。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值