08_Spring自定义标签

【 项目工程 】

 

【 Person.java 模型类 】

package com.spring.selfxml.model;

/**
 * Created by HigginCui on 2018/9/9.
 */
public class Person {

    private int age;

    private String name;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

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

【 自定义的person.xsd文件 】

<xsd:schema
        xmlns="http://higgin.com/schema"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://higgin.com/schema">
    <xsd:complexType name="complexType1">
        <xsd:attribute name="name" type="xsd:string">
            <xsd:annotation>
                <xsd:documentation><![CDATA[ The elementname1 name. ]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
        <xsd:attribute name="age" type="xsd:int">
            <xsd:annotation>
                <xsd:documentation><![CDATA[ The elementname1 age. ]]></xsd:documentation>
            </xsd:annotation>
        </xsd:attribute>
    </xsd:complexType>

    <xsd:element name="elementname1" type="complexType1">
        <xsd:annotation>
            <xsd:documentation><![CDATA[ elementname1的文档 ]]></xsd:documentation>
        </xsd:annotation>
    </xsd:element>
</xsd:schema>

[ 说明 ]

1.定义targetNamespace="http://higgin.com/schema"中,targetNamespace表示目标命名空间,xmlns的值要和这个相同

2.xsd:element定义的就是待会会在xml文件中用到的元素,例如<dubbo:application>中的application。

3.xsd:attribute定义的就是模型中的属性,例如<dubbo:application name="xxx">中的name,并且可以指定属性类型,进而起到检测的作用

 

【 spring.schemas文件 】

作用:该文件用来指定xsd文件的位置

http\://higgin.com/schema/person.xsd=META-INF/person.xsd

spring.schemas文件中的http://http/://higgin.com/schema/与person.xsd文件中的targetName相同。

 

【 PersonBeanDefinitionParser.java解析器 】

作用:用来解析自定义的xml标签

package com.spring.selfxml.shcema;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
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;

/**
 * Created by HigginCui on 2018/9/9.
 */
public class PersonBeanDefinitionParser implements BeanDefinitionParser{

    private final Class<?> beanClass;

    public PersonBeanDefinitionParser(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    public BeanDefinition parse(Element element, ParserContext parserContext) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setLazyInit(false);
        beanDefinition.getPropertyValues().add("name", element.getAttribute("name"));
        beanDefinition.getPropertyValues().add("age", element.getAttribute("age"));
        BeanDefinitionRegistry beanDefinitionRegistry = parserContext.getRegistry();
        //注册bean到BeanDefinitionRegistry中
        beanDefinitionRegistry.registerBeanDefinition(beanClass.getName(),beanDefinition);
        return beanDefinition;
    }
}

【 PersonNamespaceHandler.java命名空间处理器 】

作用:主要用来注册BeanDefinition解析器。

package com.spring.selfxml.shcema;

import com.spring.selfxml.model.Person;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

/**
 * Created by HigginCui on 2018/9/9.
 */
public class PersonNamespaceHandler extends NamespaceHandlerSupport {

    public void init() {
        registerBeanDefinitionParser("elementname1",new PersonBeanDefinitionParser(Person.class));
    }
}

说明:通常为每一个xsd:element都要注册一个BeanDefinitionParser

 

【 spring.handlers文件 】

作用:用于关联命名空间处理器PersonNamespaceHandler 和person.xsd中的targetNamespace

http\://higgin.com/schema=com.spring.selfxml.shcema.PersonNamespaceHandler

说明:这里的红色部分的key即xsd文件中的targetNamespace

 

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

    <person:elementname1 name="zhangsan" age="18"/>

</beans>

[ 说明 ]

1. xmlns:person 的 value值是 person.xml文件中的targetNamespace

2. xmlns:person可以写成 xmlns:xxx,此时<person:elementname1 ..../>就要改成<xxx:elementname1 ....>

 

【 Test.java 】

package com.spring.selfxml;

import com.spring.selfxml.model.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by HigginCui on 2018/9/9.
 */
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("person.xml");
        Person person = (Person)context.getBean(Person.class.getName());
        System.out.println(person.toString());
    }
}

【 运行结果 】

 

【 小结 】

Spring自定义xml代码的流程:

1.使用ResourceLoader将配置文件xml装在为Resource对象

2.使用BeanDefinitionReader解析配置信息:将每一个<bean>解析为一个BeanDefinition对象,然后存储到BeanDefinitionRegistry中,实际上BeanDefinitionReader调用BeanDefinitionParser进行了解析操作,解析完成后注册到BeanDefinitionRegistry。  

 

posted @ 2018-09-09 16:41  HigginCui  阅读(189)  评论(0编辑  收藏  举报