Spring 自定义命名空间解析器
1.主要步骤
主要有以下四步:
- 编写Schema文件
- 自定义NameSpaceHandler 绑定命令空间
- 自定义 BeanDefinitionParse 解析XML作为bd的配置元信息
- 命名空间映射XML
2.代码实现

需要注意的时,把 spring.handlers 文件与 spring.schemas 放在 resource目录下的META-INF文件中
Schema文件 myschema.xsd 放在任意位置均可,但后面命名空间映射XML的时候,路径不要写错
编写Schema文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.myschema.org/myschema"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.myschema.org/myschema"
           >
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
    <xsd:complexType name="My">
        <xsd:attribute name="id" type="xsd:long" use="required"/>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
        <xsd:attribute name="gender" type="gender"/>
    </xsd:complexType>
    <xsd:simpleType name="gender">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="MAN"/>
            <xsd:enumeration value="WOMAN"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:element name="my" type="My"/>
</xsd:schema>
自定义命名空间处理器 绑定命令空间
package com.sz.myschema.factory.xml;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class MyScheamNameSpaceHolder extends NamespaceHandlerSupport {
    @Override
    public void init() {
        this.registerBeanDefinitionParser("my",new MySchemaParse());
    }
}
spring.handlers
http\://www.myschema.org/myschema=com.sz.myschema.factory.xml.MyScheamNameSpaceHolder

自定义 BeanDefinitionParse 解析XML
package com.sz.myschema.factory.xml;
import com.sz.myschema.factory.bean.My;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
public class MySchemaParse extends AbstractSimpleBeanDefinitionParser {
    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        setPropertyValue("id",element,builder);
        setPropertyValue("name",element,builder);
        setPropertyValue("gender",element,builder);
    }
    public void setPropertyValue(String id,Element element,BeanDefinitionBuilder builder){
        builder.addPropertyValue(id,element.getAttribute(id));
    }
    @Override
    protected Class<?> getBeanClass(Element element) {
        return My.class;
    }
}
命名空间映射XML
spring.schemas
http\://www.myschema.org/myschema.xsd=META-INF/myschema.xsd

3.测试
spring.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:myschema="http://www.myschema.org/myschema"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.myschema.org/myschema
        http://www.myschema.org/myschema.xsd">
    <myschema:my id="18" name="zhangsan" gender="MAN"/>
</beans>
测试类
package com.sz.myschema;
import com.sz.myschema.factory.bean.My;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
public class App {
    public static void main(String[] args) {
        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
        xmlBeanDefinitionReader.loadBeanDefinitions("classpath:spring-config.xml");
        My bean = defaultListableBeanFactory.getBean(My.class);
        System.out.println("bean = " + bean);
    }
}
输出结果
bean = My{id=18, name='zhangsan', gender='MAN'}
完整代码 :https://gitcode.net/JAVAlife2021/spring.git



















