美文网首页
自定义spring XSD

自定义spring XSD

作者: 御风_2fd9 | 来源:发表于2021-02-18 10:55 被阅读0次

    XSD XML Schema Definition,即xml标签定义,在spring中,标签都是spring定义好的。
    本文演示自定义XSD的过程。

    一、项目结构

    image.png

    二、步骤如下:

    2.1. 定义一个XSD文件。
    在resources的META-INF下新建一个xsd文件,model.xsd

    <?xml version="1.0"?>
    <xsd:schema
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://xsj.example.com/schema"
            targetNamespace="http://xsj.example.com/schema">
        <xsd:complexType name="studentType">
            <xsd:attribute name="id" type="xsd:int">
            </xsd:attribute>
            <xsd:attribute name="name" type="xsd:string">
            </xsd:attribute>
        </xsd:complexType>
        <xsd:element name="student" type="studentType">
        </xsd:element>
    </xsd:schema>
    

    2.2. 定义一个和XSD文件所对应的实体类。

    package org.example.model;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.ToString;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Student  {
        private int id;
        private String name;
    }
    

    2.3. 创建实现了BeanDefinitionParser的类(其实更好的做法是继承抽象类AbstractBeanDefinitionParser),解析自定义标签。

    package org.example.spring;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.support.GenericBeanDefinition;
    import org.springframework.beans.factory.xml.BeanDefinitionParser;
    import org.springframework.beans.factory.xml.ParserContext;
    import org.w3c.dom.Element;
    
    public class StudentBeanDefinitionParser implements BeanDefinitionParser {
        private final Class<?> beanClass;
    
        public StudentBeanDefinitionParser(Class<?> beanClass) {
            this.beanClass = beanClass;
        }
        @Override
        public BeanDefinition parse(Element element, ParserContext parserContext) {
            GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
            genericBeanDefinition.setBeanClass(beanClass);
            genericBeanDefinition.setLazyInit(false);
            genericBeanDefinition.getPropertyValues().add("id", element.getAttribute("id"));
            genericBeanDefinition.getPropertyValues().add("name", element.getAttribute("name"));
            parserContext.getRegistry().registerBeanDefinition(beanClass.getName(),genericBeanDefinition);
            return null;
        }
    }
    

    2.4. 创建一个继承了NamespaceHandlerSupport的类,将我们创建的类注册到spring容器。

    package org.example.spring;
    import org.example.model.Student;
    import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
    
    public class MyNameSpaceHandler extends NamespaceHandlerSupport {
        @Override
        public void init() {
            registerBeanDefinitionParser("student",new StudentBeanDefinitionParser(Student.class));
        }
    }
    

    2.5. 编写自己的spring.handlers和spring.schemas
    在resources的META-INF下新建spring.handlers和spring.schemas文件。

    • spring.handlers
      spring.handlers的key要和步骤1 model.xsd中的xmlns保持一致,反斜杠是为了转义。
      value是NamespaceHandlerSupport全限定名。


      image.png
    http\://xsj.example.com/schema=org.example.spring.MyNameSpaceHandler
    
    • spring.schemas
      key要和步骤1 model.xsd中的xmlns保持一致,反斜杠是为了转义。
      value是model.xsd的位置。
    http\://xsj.example.com/schema/model.xsd=META-INF/model.xsd
    

    三、测试验证

    3.1 在resources下创建一个application-context.xml文件(名称随意)。
    文件头说明:

    1. beans表示xml文件的根节点
    2. xmlns 是XML NameSpace的缩写,因为XML文件的标签名称都是自定义的,自己写的和其他人定义的标签很有可能会重复命名,而功能却不一样,所以需要加上一个namespace来区分这个xml文件和其他的xml文件,类似于java中的package。
    3. xmlns:xsi ——是指xml文件遵守xml规范,xsi全名:xml schema instance,是指具体用到的schema资源文件里定义的元素所准守的规范。即http://www.w3.org/2001/XMLSchema-instance这个文件里定义的元素遵守什么标准
    4. xsi:schemaLocation——是指本文档里的xml元素所遵守的规范,这些规范都是由官方制定的,可以进你写的网址里面看版本的变动。xsd的网址还可以帮助你判断使用的代码是否合法。
      xsi:schemaLocation 前一部分是前面xmlns的值,后一部分是xsd的存放地址,构成规则是xmlns+xsd名称。
      比如自定义的xmlns,http://xsj.example.com/schema 是自定义标签的namespace,spring根据xsi:schemaLocation中的路径,http://xsj.example.com/schema/model.xsd去网络上找,如果找不到,就会去本地spring.schemas中定义的映射关系找,从而找到了本地的META-INF/model.xsd文件。
    <?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:xsj="http://xsj.example.com/schema"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                                http://xsj.example.com/schema http://xsj.example.com/schema/model.xsd">
    
        <xsj:student id="1" name="xushengjun"/>
    
    </beans>
    

    3.2 创建一个测试类

    package org.example;
    
    import org.example.model.Student;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Application {
    
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:application-context.xml");
    
            Student student = ctx.getBean(Student.class);
            System.out.println(student);
        }
    }
    
    

    3.3 输出结果

    Student(id=1, name=xushengjun)
    
    Process finished with exit code 0
    

    参考:
    https://www.cnblogs.com/shamo89/p/9925538.html
    https://www.cnblogs.com/myitnews/p/14018916.html

    相关文章

      网友评论

          本文标题:自定义spring XSD

          本文链接:https://www.haomeiwen.com/subject/wregxltx.html