自定義spring XSD

XSD XML Schema Definition,即xml標(biāo)簽定義,在spring中,標(biāo)簽都是spring定義好的。
本文演示自定義XSD的過(guò)程。

一、項(xiàng)目結(jié)構(gòu)

image.png

二、步驟如下:

2.1. 定義一個(gè)XSD文件。
在resources的META-INF下新建一個(gè)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. 定義一個(gè)和XSD文件所對(duì)應(yīng)的實(shí)體類(lèi)。

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. 創(chuàng)建實(shí)現(xiàn)了BeanDefinitionParser的類(lèi)(其實(shí)更好的做法是繼承抽象類(lèi)AbstractBeanDefinitionParser),解析自定義標(biāo)簽。

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. 創(chuàng)建一個(gè)繼承了NamespaceHandlerSupport的類(lèi),將我們創(chuàng)建的類(lèi)注冊(cè)到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. 編寫(xiě)自己的spring.handlers和spring.schemas
在resources的META-INF下新建spring.handlers和spring.schemas文件。

  • spring.handlers
    spring.handlers的key要和步驟1 model.xsd中的xmlns保持一致,反斜杠是為了轉(zhuǎn)義。
    value是NamespaceHandlerSupport全限定名。


    image.png
http\://xsj.example.com/schema=org.example.spring.MyNameSpaceHandler
  • spring.schemas
    key要和步驟1 model.xsd中的xmlns保持一致,反斜杠是為了轉(zhuǎn)義。
    value是model.xsd的位置。
http\://xsj.example.com/schema/model.xsd=META-INF/model.xsd

三、測(cè)試驗(yàn)證

3.1 在resources下創(chuàng)建一個(gè)application-context.xml文件(名稱(chēng)隨意)。
文件頭說(shuō)明:

  1. beans表示xml文件的根節(jié)點(diǎn)
  2. xmlns 是XML NameSpace的縮寫(xiě),因?yàn)閄ML文件的標(biāo)簽名稱(chēng)都是自定義的,自己寫(xiě)的和其他人定義的標(biāo)簽很有可能會(huì)重復(fù)命名,而功能卻不一樣,所以需要加上一個(gè)namespace來(lái)區(qū)分這個(gè)xml文件和其他的xml文件,類(lèi)似于java中的package。
  3. xmlns:xsi ——是指xml文件遵守xml規(guī)范,xsi全名:xml schema instance,是指具體用到的schema資源文件里定義的元素所準(zhǔn)守的規(guī)范。即http://www.w3.org/2001/XMLSchema-instance這個(gè)文件里定義的元素遵守什么標(biāo)準(zhǔn)
  4. xsi:schemaLocation——是指本文檔里的xml元素所遵守的規(guī)范,這些規(guī)范都是由官方制定的,可以進(jìn)你寫(xiě)的網(wǎng)址里面看版本的變動(dòng)。xsd的網(wǎng)址還可以幫助你判斷使用的代碼是否合法。
    xsi:schemaLocation 前一部分是前面xmlns的值,后一部分是xsd的存放地址,構(gòu)成規(guī)則是xmlns+xsd名稱(chēng)。
    比如自定義的xmlns,http://xsj.example.com/schema 是自定義標(biāo)簽的namespace,spring根據(jù)xsi:schemaLocation中的路徑,http://xsj.example.com/schema/model.xsd去網(wǎng)絡(luò)上找,如果找不到,就會(huì)去本地spring.schemas中定義的映射關(guān)系找,從而找到了本地的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 創(chuàng)建一個(gè)測(cè)試類(lèi)

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 輸出結(jié)果

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容