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。