SpringBoot之自定义Schema扩展方式

目录

  • SpringBoot 自定义Schema扩展
    • 1. 配置ServiceConfig属性
    • 2. 编写XSD文件
    • 3. 编写NamespaceHandler
    • 4. 编写BeanDefinitionParser
    • 5. 配置spring.handlers和spring.schemas
    • 6. 配置spring的加载文件
    • 7. 测试
  • Spring Schema扩展机制
    • 1. 概述
    • 2. 步骤
    • 3. 示例如下

SpringBoot 自定义Schema扩展 最近在写RPC框架时,用到了自定义的xsd配置。我们平时习惯于使用bean配置实例化对象,因此把xsd这种方式单独拎出来。

1. 配置ServiceConfig属性
@Datapublic class ServiceConfig {/** 接口 */private String interfaceClass; /** 引用 */private String ref; /** 版本 */private String version; @Overridepublic String toString() {return "ServiceConfig{" +"interfaceClass='" + interfaceClass + '\'' +", ref='" + ref + '\'' +", version='" + version + '\'' +'}'; }}


2. 编写XSD文件
配置element的name为service,配置的attribute对应ServiceConfig定义的属性


3. 编写NamespaceHandler
registerBeanDefinitionParser方法的key是xsd配置的element的name,表示service元素由LinkServiceBeanDefinitionParser对象解析
public class LinkNamespaceHandler extends NamespaceHandlerSupport {@Overridepublic void init() {this.registerBeanDefinitionParser("service", new LinkServiceBeanDefinitionParser()); }}


4. 编写BeanDefinitionParser
从element中解析出属性,注册到BeanDefinitionBuilder
public class LinkServiceBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {@Overrideprotected Class getBeanClass(Element element) {return ServiceConfig.class; } @Overrideprotected void doParse(Element element, BeanDefinitionBuilder bean) {bean.addPropertyValue("ref", element.getAttribute("ref")); bean.addPropertyValue("interfaceClass", element.getAttribute("interfaceClass")); bean.addPropertyValue("version", element.getAttribute("version")); }}


5. 配置spring.handlers和spring.schemas
http\://gitee.com/schema/link=com.test.xsd.handler.LinkNamespaceHandlerhttp\://gitee.com/schema/link/link.xsd=META-INF/link.xsd


6. 配置spring的加载文件
在文件头部需要引入link的schema


7. 测试
public class App { public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("link-server.xml"); ServiceConfig config = (ServiceConfig) context.getBean("serviceConfig"); System.out.println(config.toString()); }}


Spring Schema扩展机制
1. 概述
Spring2.0开始,Spring提供XML Schema可扩展机制,用户可以自定义XML Schema文件,并自定义
XML Bean解析器,集成到Spring IOC容器中。

2. 步骤
创建一个XML Schema文件,描述自定义的合法构建模块,也就是xsd文件。
自定义处理器类,并实现NamespaceHandler接口。
自定义一个或者多个解析器,实现BeanDefinitionParser接口(关键部分)。
注册上面的组建到Spring IOC容器。

3. 示例如下
(1) 自定义XML Schema文件
??

自定义targetNamespace是http://www.liuenyuan.com/schema/myns,xmlns与命名空间必须一致。
(2) 自定义NamespaceHandler
NamespaceHandler接口只有三个方法
  • init():在NamespaceHandler被使用之前调用,完成初始化
  • parse():解析元素
  • decorate():嵌套元素时候调用
Spring提供一个默认实现类NamespaceHandlerSupport,注入每个元素的解析器即可。
用到了代理委托概念。NamespaceHandlerSupport可以注册任意个BeanDefinitionParser,负责所有自定义元素编排,实际XML解析工作委托给各个BeanDefinitioParser负责。
(3) 自定义BeanDefinitionParser
BeanDefinitionParser 将被调用,如果NamespapceHandler遇到元素类型已经有对应注册的parser(例如上面的handler如果遇到dateformat,DateformatDefinitionParser会被调用,
解析相应的属性设置到Bean中)将会被调用。BeanDefinitionParser负责解析一个顶级元素。
Spring提供AbstractSingleBeanDefinitionParser处理繁重的解析工作。
  • getBeanClass():返回元素Class类型
  • doParse():添加元素属性或者构造参数
(4) 注册handler和schema
把实现的NamespaceHandler和xsd文件配置到指定的配置文件中。位于META-INF目录中。
spring.handlers文件包含xml schema uri和Handler类映射关系。
http\://www.liuenyuan.com/schema/myns=\com.ley.springboot.schema.xml.MynsNamespaceHandler

遇到http\://www.liuenyuan.com/schema/myns命名空间的时候会交给MynsNamespaceHandler来处理,key部分必须和xsd文件中的targetNamespace值保持一致
spring.schemas文件包含xml schema xsd文件命名空间和文件路径映射关系。
http\://www.liuenyuan.com/schema/myns.xsd=META-INF/myns.xsd

(5) 测试
NamespaceHandler实现类
public class MynsNamespaceHandler extends NamespaceHandlerSupport {?@Overridepublic void init() {registerBeanDefinitionParser("dateFormat", new MynsBeanDefinitionParser()); }}

BeaDefinitionParser实现类
import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.w3c.dom.Element; ?import java.text.SimpleDateFormat; ?public class MynsBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {?@Overrideprotected Class getBeanClass(Element element) {return SimpleDateFormat.class; }?@Overrideprotected void doParse(Element element, BeanDefinitionBuilder builder) {String pattern = element.getAttribute("pattern"); builder.addConstructorArgValue(pattern); }}

【SpringBoot之自定义Schema扩展方式】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读