SpringBoot之自定义Schema扩展方式

网友投稿 791 2022-12-05

SpringBoot之自定义Schema扩展方式

SpringBoot之自定义Schema扩展方式

目录SpringBoot 自定义Schema扩展1. 配置ServiceConfig属性2. 编写XSD文件3. 编写NamespaceHandler4. 编写BeanDefinitionParser5. 配置spring.handlers和spring.schemas6. 配置spring的加载文件7. 测试Spring Schema扩展机制http://1. 概述2. 步骤3. 示例如下

SpringBoot 自定义Schema扩展

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

1. 配置ServiceConfig属性

@Data

public class ServiceConfig {

/** 接口 */

private String interfaceClass;

/**NNvVhZTABq 引用 */

private String ref;

/** 版本 */

private String version;

@Override

public String toString() {

return "ServiceConfig{" +

"interfaceClass='" + interfaceClass + '\'' +

", ref='" + ref + '\'' +

", version='" + version + '\'' +

'}';

}

}

2. 编写XSD文件

配置element的name为service,配置的attribute对应ServiceConfig定义的属性

xmlns:xsd="http://w3.org/2001/XMLSchema"

xmlns:beans="http://springframework.org/schema/beans"

targetNamespace="http://gitee.com/schema/link"

elementFormDefault="qualified">

<![CDATA[ 服务接口实现类]]>

http://

<![CDATA[服务接口]]>

xmlns:xsd="http://w3.org/2001/XMLSchema"

xmlns:beans="http://springframework.org/schema/beans"

targetNamespace="http://gitee.com/schema/link"

elementFormDefault="qualified">

<![CDATA[ 服务接口实现类]]>

http://

<![CDATA[服务接口]]>

3. 编写NamespaceHandler

registerBeanDefinitionParser方法的key是xsd配置的element的name,表示service元素由LinkServiceBeanDefinitionParser对象解析

public class LinkNamespaceHandler extends NamespaceHandlerSupport {

@Override

public void init() {

this.registerBeanDefinitionParser("service", new LinkServiceBeanDefinitionParser());

}

}

4. 编写BeanDefinitionParser

从element中解析出属性,注册到BeanDefinitionBuilder

public class LinkServiceBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

@Override

protected Class getBeanClass(Element element) {

return ServiceConfig.class;

}

@Override

protected 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.LinkNamespaceHandler

http\://gitee.com/schema/link/link.xsd=META-INF/link.xsd

6. 配置spring的加载文件

在文件头部需要引入link的schema

xmlns:link="http://gitee.com/schema/link"

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://gitee.com/schema/link http://gitee.com/schema/link/link.xsd">

ref="helloService"

interfaceClass="com.test.service.HelloService"

version="1.0.0"/>

xmlns:link="http://gitee.com/schema/link"

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://gitee.com/schema/link http://gitee.com/schema/link/link.xsd">

ref="helloService"

interfaceClass="com.test.service.HelloService"

version="1.0.0"/>

ref="helloService"

interfaceClass="com.test.service.HelloService"

version="1.0.0"/>

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文件

xmlns:xsd="http://w3.org/2001/XMLSchema"

xmlns:beans="http://springframework.org/schema/beans"

targetNamespace="http://liuenyuan.com/schema/myns"

elementFormDefault="qualified">

xmlns:xsd="http://w3.org/2001/XMLSchema"

xmlns:beans="http://springframework.org/schema/beans"

targetNamespace="http://liuenyuan.com/schema/myns"

elementFormDefault="qualified">

自定义targetNamespace是http://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\://liuenyuan.com/schema/myns=\

com.ley.springboot.schema.xml.MynsNamespaceHandler

遇到http\://liuenyuan.com/schema/myns命名空间的时候会交给MynsNamespaceHandler来处理,key部分必须和xsd文件中的targetNamespace值保持一致

spring.schemas文件包含xml schema xsd文件命名空间和文件路径映射关系。

http\://liuenyuan.com/schema/myns.xsd=META-INF/myns.xsd

(5) 测试

NamespaceHandler实现类

public class MynsNamespaceHandler extends NamespaceHandlerSupport {​

@Override

public 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 {​

@Override

protected Class> getBeanClass(Element element) {

return SimpleDateFormat.class;

}

@Override

protected void doParse(Element element, BeanDefinitionBuilder builder) {

String pattern = element.getAttribute("pattern");

builder.addConstructorArgValue(pattern);

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:使用idea远程调试jar包的配置过程
下一篇:Spring Security基于散列加密方案实现自动登录功能
相关文章

 发表评论

暂时没有评论,来抢沙发吧~