我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SpringBoot之自定义Schema扩展方式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SpringBoot之自定义Schema扩展方式

SpringBoot 自定义Schema扩展

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

1. 配置ServiceConfig属性


@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定义的属性


<?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对象解析


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


<?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. 测试


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


<?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类映射关系。


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 {​
    @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);
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SpringBoot之自定义Schema扩展方式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Spring自定义XML schema 扩展的示例分析

小编给大家分享一下Spring自定义XML schema 扩展的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Spring整合dubbo的事例
2023-06-15

jquery怎么扩展自定义方法

要扩展自定义方法,可以使用jQuery的`$.fn`命名空间。下面是一个简单的示例:```javascript// 扩展自定义方法$.fn.customMethod = function() {// 在这里编写自定义方法的代码// 使用th
2023-08-12

django之对django内置的User模型进行自定义扩展方式

目录问题解决1.首先查看内置User模型的源码:2.因此要实现内置User模型的扩展总结问题实际开发中可能内置User模型的字段不能满足需要。解决1.首先查看内置User模型的源码:MyDjango\venv\Scripts\pyt
2023-05-12

layui table组件的样式定制与扩展(自定义和扩展layui table组件样式的方法)

LayuiTable组件样式定制与扩展指南本指南介绍了使用LayuiTable组件进行样式定制和扩展的方法。样式定制:使用内置主题或创建自定义主题。覆盖默认样式以实现自定义外观。扩展:添加自定义列,支持多种数据类型。添加工具栏,提供搜索、排序等操作。与其他Layui组件整合,增强交互性。掌握这些技巧,开发者可以为LayuiTable组件创建个性化且功能强大的界面,提升用户体验。
layui table组件的样式定制与扩展(自定义和扩展layui table组件样式的方法)
2024-04-02

PHP自定义扩展之生命周期的示例分析

这篇文章将为大家详细讲解有关PHP自定义扩展之生命周期的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。php_request_startup这个阶段和php_module_startup差不多,都
2023-06-22

SpringBoot @Cacheable自定义KeyGenerator方式是什么

这篇文章主要介绍“SpringBoot @Cacheable自定义KeyGenerator方式是什么”,在日常操作中,相信很多人在SpringBoot @Cacheable自定义KeyGenerator方式是什么问题上存在疑惑,小编查阅了各
2023-06-22

DEDECMS 扩展标签和dede自定义标签实现方法

我们需要知道下扩展标签的存放目录及文件名构成,首先,扩展的标签都是存放在/include/taglib这个目录,名称都是以“标签名.lib.php”格式,例如{dede:channel/}标签对应的是channel.
2022-06-12

织梦CMS扩展功能:自定义字段的应用方法

织梦CMS(DedeCMS)是一款国产的开源内容管理系统,广泛应用于各类网站建设中。其强大的扩展功能让用户可以根据自身需求进行定制化开发。其中,自定义字段是一项非常有用的功能,可以方便用户在后台添加自定义内容,提升网站的灵活性和扩展性。本文
织梦CMS扩展功能:自定义字段的应用方法
2024-03-13

SpringBoot自定义错误页面方式有哪些

这篇文章主要讲解了“SpringBoot自定义错误页面方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot自定义错误页面方式有哪些”吧!以前web.xml方式先来看下
2023-06-21

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录