gpt4 book ai didi

SpringBoot之自定义Schema扩展方式

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 33 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章SpringBoot之自定义Schema扩展方式由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

SpringBoot 自定义Schema扩展

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

1. 配置ServiceConfig属性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Data
public class ServiceConfig {
     /** 接口 */
     private String interfaceClass;
 
     /** 引用 */
     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定义的属性 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<? xml version = "1.0" encoding = "UTF-8" ?>
< xsd:schema xmlns = "http://gitee.com/schema/link"
                 xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
                 xmlns:beans = "http://www.springframework.org/schema/beans"
                 targetNamespace = "http://gitee.com/schema/link"
                 elementFormDefault = "qualified" >
     < xsd:import namespace = "http://www.springframework.org/schema/beans" />
     < xsd:import namespace = "http://www.springframework.org/schema/tool" />
 
     < xsd:element name = "service" >
         < xsd:complexType >
             < xsd:complexContent >
                 < xsd:extension base = "beans:identifiedType" >
                     < xsd:attribute name = "ref" type = "xsd:string" use = "required" >
                         < xsd:annotation >
                             < xsd:documentation > <![CDATA[ 服务接口实现类]]> </ xsd:documentation >
                         </ xsd:annotation >
                     </ xsd:attribute >
                     < xsd:attribute name = "interfaceClass" type = "xsd:string" use = "required" >
                         < xsd:annotation >
                             < xsd:documentation > <![CDATA[服务接口]]> </ xsd:documentation >
                         </ xsd:annotation >
                     </ xsd:attribute >
                     < xsd:attribute name = "version" type = "xsd:string" />
                 </ xsd:extension >
             </ xsd:complexContent >
         </ xsd:complexType >
     </ xsd:element >
</ xsd:schema >

3. 编写NamespaceHandler

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

?
1
2
3
4
5
6
public class LinkNamespaceHandler extends NamespaceHandlerSupport {
     @Override
     public void init() {
         this .registerBeanDefinitionParser( "service" , new LinkServiceBeanDefinitionParser());
     }
}

4. 编写BeanDefinitionParser

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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

?
1
2
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 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans"
        xmlns:link = "http://gitee.com/schema/link"
        xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://gitee.com/schema/link http://gitee.com/schema/link/link.xsd">
 
     <!-- rpc服务 -->
     < link:service id = "serviceConfig"
                   ref = "helloService"
                   interfaceClass = "com.test.service.HelloService"
                   version = "1.0.0" />
</ beans >

7. 测试

?
1
2
3
4
5
6
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文件 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<? xml version = "1.0" encoding = "UTF-8" ?>​
< xsd:schema xmlns = "http://www.liuenyuan.com/schema/myns"
             xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
             xmlns:beans = "http://www.springframework.org/schema/beans"
             targetNamespace = "http://www.liuenyuan.com/schema/myns"
             elementFormDefault = "qualified" >
     < xsd:import namespace = "http://www.springframework.org/schema/beans" />
     < xsd:element name = "dateFormat" >
         < xsd:complexType >
             < xsd:complexContent >
                 < xsd:extension base = "beans:identifiedType" >
                     < xsd:attribute name = "pattern" type = "xsd:string" use = "required" />
                 </ xsd:extension >
             </ xsd:complexContent >
         </ xsd:complexType >
     </ xsd:element >
</ xsd: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类映射关系.

?
1
2
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文件命名空间和文件路径映射关系.

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

(5) 测试 。

NamespaceHandler实现类 。

?
1
2
3
4
5
6
public class MynsNamespaceHandler extends NamespaceHandlerSupport {​
     @Override
     public void init() {
         registerBeanDefinitionParser( "dateFormat" , new MynsBeanDefinitionParser());
     }
}

BeaDefinitionParser实现类 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
     }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.

原文链接:https://blog.csdn.net/ghaohao/article/details/81116761 。

最后此篇关于SpringBoot之自定义Schema扩展方式的文章就讲到这里了,如果你想了解更多关于SpringBoot之自定义Schema扩展方式的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com