Spring Boot自定义Namespace

news2024/11/26 8:22:03

Spring Boot 自定义Namespace

在学些Spring Boot 自定义Namespace之前,先来看一个简单的案例。在Spring Boot出现之前,所有的bean都是在XML文件的格式

中定义。为了管理方便,一些大型复杂的应用系统,通常定个多个xml文件来共同满足业务需求,如业务bean、datasource 定义、业务拦

截bean定义等等。

为了弄清楚Spring Boot Namespace的运行原理,先从一个最简单的demo开始

基础应用

bean class

定义一个普通的学员类,包含学员id、姓名、年龄、专业属性,并使用lombok生成get、set方法

@Data
@ToString
public class Student implements Serializable {

    private Long id;

    // 姓名
    private String name;

    // 年龄
    private byte age;

    // 专业
    private String major;
}

bean xml 定义

在resources目录下创建 xml/spring-beans.xml 文件,内容如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
    <bean id="student" class="com.springboot.study.springbootstudy.bean.Student">
        <property name="id" value="1000"/>
        <property name="name" value="科比"/>
        <property name="age" value="38"/>
        <property name="major" value="篮球"/>
    </bean>
</beans>

bean 应用

在Spring Boot 启动类中使用 @ImportResource 引入xml 配置文件,就可以使用bean了

@SpringBootApplication
@ImportResource(locations= {"classpath:xml/spring-beans.xml"})

public class SpringbootStudyApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext app = SpringApplication.run(SpringbootStudyApplication.class, args);
		
		final Student student = app.getBean(Student.class);
		System.out.println("Spring Boot Student =================: " + student);
    // 输出如下
    // Spring Boot Student =================: Student(id=1000, name=科比, age=38, major=篮球)
	}
}

至此,已经完成了bean的定义到应用的基本流程,简单吧。相信学习过dubbo框架的同学对下面的代码特别熟悉

<dubbo:application name="demo-consumer"/>

<dubbo:registry address="zookeeper://localhost:2181"/>

<dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.demo.DemoService"/>

通过自定义dubbo命名空间, 完成bean的装载与逻辑处理。那么我们了解其内部原理后,也可以开发出自己的开源框架了。

bean 解析原理

在这里插入图片描述

点击右侧的URL后,定位到dubbo.xsd文件和以两个spring开头的文件信息

  • dubbo.xsd - 定义了以dubbo为命名空间的语法,对里面的内容做了限定

  • spring.handlers - 里面定义了dubbo.xsd 解析类,在运行时使用SPI的方式动态加载

    http\://dubbo.apache.org/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
    http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
    
  • spring.schemas - 将xsd文件、与命名空间关联起来

    http\://dubbo.apache.org/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
    http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/compat/dubbo.xsd
    

现在来梳理下这三部分之间的关系

定义xsd文件 —> xsd文件关联schemas ----> 定义解析处理类

在这里插入图片描述

需要注意的是,dubbo中的每个模块都一一对应一个xml 解析器,这里如果不一致则会报以下错误

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [application]

接下来,我们依葫芦画瓢实现一个自定义的Namespace处理流程

自定义Namespace

xsd 定义

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:beans="http://www.springframework.org/schema/beans"
            xmlns:tool="http://www.springframework.org/schema/tool"
            xmlns="http://xml.definition.com/schema/custom"
            targetNamespace="http://xml.definition.com/schema/custom">

    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
    <xsd:import namespace="http://www.springframework.org/schema/beans"/>
    <xsd:import namespace="http://www.springframework.org/schema/tool"/>

    <xsd:complexType name="applicationType">
        <xsd:attribute name="id" type="xsd:long"/>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
        <xsd:attribute name="age" type="xsd:byte"/>
        <xsd:attribute name="major" type="xsd:string"/>
    </xsd:complexType>

    <xsd:element name="application" type="applicationType"/>
</xsd:schema>

schemas 定义

http\://xml.definition.com/schema/custom.xsd=META-INF/student.xsd

handlers 定义

http\://xml.definition.com/schema/custom=com.springboot.study.springbootstudy.handler.CustomNamespaceHandler

关联代码

  • CustomNamespaceHandler - 自定义的Namespace的处理代码如下

    public class CustomNamespaceHandler extends NamespaceHandlerSupport {
        /**
         * 自定义标签解析 生成bean 对象
         */
        @Override
        public void init() {
            System.out.println("==================================== CustomNamespaceHandler execute");
            this.registerBeanDefinitionParser("application",new CustomBeanDefinitionParser());
        }
    }
    
  • CustomBeanDefinitionParser - xml 解析代码如下

    package com.springboot.study.springbootstudy.handler;
    
    import com.springboot.study.springbootstudy.bean.Student;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.support.RootBeanDefinition;
    import org.springframework.beans.factory.xml.BeanDefinitionParser;
    import org.springframework.beans.factory.xml.ParserContext;
    import org.w3c.dom.Element;
    
    public class CustomBeanDefinitionParser implements BeanDefinitionParser {
    
        /**
         * 解析xml文件 动态注册bean 至ioc容器中
         * @param element
         * @param parserContext
         * @return
         */
        public BeanDefinition parse(Element element, ParserContext parserContext) {
            //beanDefinition
            RootBeanDefinition beanDefinition = new RootBeanDefinition();
            beanDefinition.setBeanClass(Student.class);
            beanDefinition.setLazyInit(false);
            //beanDefinition.setScope();
            //解析id
            String id = element.getAttribute("id");
            beanDefinition.getPropertyValues().add("id", id);
            //解析name
            beanDefinition.getPropertyValues().add("name",
                    element.getAttribute("name"));
            //解析 age
            beanDefinition.getPropertyValues().add("age",
                    element.getAttribute("age"));
            //major
            beanDefinition.getPropertyValues().add("major",
                    element.getAttribute("major"));
    
            parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
            return beanDefinition;
    
        }
    }
    

    至此已经完成了一个简单版的自定义Namespace所有功能开发,接下来测试一下。

测试验证

修改spring-beans.xml 文件,现在使用自定义Namespace的方式注册bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:custom="http://xml.definition.com/schema/custom"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://xml.definition.com/schema/custom
        http://xml.definition.com/schema/custom.xsd">

<!--    <bean id="student" class="com.springboot.study.springbootstudy.bean.Student">-->
<!--        <property name="id" value="1000"/>-->
<!--        <property name="name" value="科比"/>-->
<!--        <property name="age" value="38"/>-->
<!--        <property name="major" value="篮球"/>-->
<!--    </bean>-->
	<custom:application id="1000" name="科比" age="38" major="篮球"/>
</beans>

然后重新启动应用程序,依然可以获取xml中 student bean 定义的内容。

源码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/42659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【笑小枫的按步照搬系列】JDK8下载安装配置

笑小枫&#x1f495; 欢迎来到笑小枫的世界&#xff0c;喜欢的朋友关注一下我呦&#xff0c;大伙的支持&#xff0c;就是我坚持写下去的动力。 微信公众号&#xff1a;笑小枫 笑小枫个人博客&#xff1a;https://www.xiaoxiaofeng.com 一、安装 1、方式一&#xff1a;进入官网…

Apifox:成熟的测试工具要学会自己写接口文档

好家伙&#xff0c; 在开发过程中&#xff0c;我们总是避免不了进行接口的测试&#xff0c; 而相比手动敲测试代码&#xff0c;使用测试工具进行测试更为便捷&#xff0c;高效 今天发现了一个非常好用的接口测试工具Apifox 相比于Postman&#xff0c;他还拥有一个非常nb的功…

读《基于深度学习的跨视角步态识别算法研究》

2020 背景&#xff1a; 作为一种新兴的识别技术&#xff0c;步态识别具有在非受控、远距离、低分辨率的场景下进行身份识别的优点&#xff0c;并且步态不易改变和伪装&#xff0c;所以近年来得到的关注逐渐增多。 步态识别作为一种新兴的身份识别技术&#xff0c;可以根据人…

jsp美食管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 美食管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统采用serlvet dao bean mvc模式开发&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Myeclipse8…

ZYNQ之FPGA学习----UART串口实验

1 UART串口简介 UART串口基础知识学习&#xff1a;硬件设计基础----通信协议UART 2 实验任务 上位机通过串口调试助手发送数据给 Zynq&#xff0c;Zynq PL 端通过 RS232 串口接收数据并将接收到的数据发送给上位机&#xff0c;完成串口数据环回&#xff0c;管脚分配如下&…

软件测试的分类

这里先讲一些概念&#xff0c;改日从这里边挑几个细讲。&#xff08;给小白看的&#xff09; 按测试对象划分&#xff1a; 界面测试&#xff1a; 软件只是一种工具&#xff0c;软件与人的信息交流是通过界面来进行的&#xff0c;界面是软件与用户交流的最直接的一层&#xff…

基于二次近似(BLEAQ)的双层优化进化算法_matlab程序

参考文献如上。 双层优化问题是一类具有挑战性的优化问题&#xff0c;包含两个层次的优化任务。在这些问题中&#xff0c;下层问题的最优解成为上层问题的可能可行候选。这样的要求使得优化问题难以解决&#xff0c;并使研究人员忙于设计能够有效处理该问题的方法。尽管付出了…

Redis常见面试问题总结

文章目录Redis 基础面试说说你对Redis的了解?说说Redis中的数据类型&#xff1f;说说Redis数据类型对应的数据结构&#xff1f;说说Redis对应的Java客户端有哪些&#xff1f;说说Redis 中持久化发生了什么&#xff1f;说说Redis中持久化以及方式&#xff1f;如何理解Redis中RD…

2022年超实用的推特营销策略

Twitter推广需知的13条基础知识&#xff1a; 1、Twitter日活用户达1亿 2、Twitter月活用户3.25亿 3、Twitter广告价格比其他渠道便宜33% 4、每天产生5亿条推文 5、Twitter推广能够提高29%的线下交易 6、37%的Twitter用户在18到29岁之间 7、86%的带链接推文会比普通推文效…

JUC并发编程与源码分析笔记03-CompletableFuture

Future接口理论知识复习 Future接口&#xff08;FutureTask实现类&#xff09;定义了操作异步任务执行的一些方法&#xff0c;如获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。 找到java.util.concurrent.Future&#xff0c;看到里面…

Node.js 入门教程 22 将所有 Node.js 依赖包更新到最新版本

Node.js 入门教程 Node.js官方入门教程 Node.js中文网 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录Node.js 入门教程22 将所有 Node.js 依赖包更新到最新版本22 将所有 Node.js 依赖包更新到最新版本 当使用 npm install <packagename&g…

pytorch 手写数字识别1

目录 概述 加载图片 绘图部分 backward 前言&#xff1a; 这里以一个手写数字识别的例子,简单了解一下pytorch 实现神经网络的过程. 本章重点讲一下加载数据过程 参考&#xff1a; 课时9 手写数字识别初体验-1_哔哩哔哩_bilibili Pytorch中的backward函数 - …

为了让线上代码可追溯, 我开发了这个vite插件

人生的第一个vite插件 前言 想在控制台输出一下前端代码的一些构建信息&#xff0c; 比如打包时间、打包的人, 代码分支、commit是那个&#xff0c;方便在控制台追溯。 背景 遇到的问题 1、场景一 前端多人协同开发的情况下&#xff0c;比方测试站&#xff0c; 你发的代码…

Java 反射系列 —— 学习笔记

Java 反射系列 1. 类成员 为了更好的描述&#xff0c;我们做个约定个通配符 XXXX&#xff0c; 如果是成员变量就代表 Field&#xff0c;如果是类方法就代表 Method&#xff0c;如果是构造器就代表 Constructor。 1.1 获取方法 那么怎么获取到这三类成员呢&#xff1f; 获…

逆势涨薪3k!新媒体运营毅然转行测试,我的入行秘籍是什么?

不尝试永远都不会成功&#xff0c;勇敢的尝试是成功的一半。 大学毕业做运营&#xff0c;业务难精进&#xff0c;薪资难提升 “你大学专业是商务英语&#xff0c;为什么毕业后会选择做新媒体运营呢&#xff1f;” 其实我当时没有想那么多的&#xff0c;商务英语的就业方向一个…

苹果电容笔值得买吗?2022最新电容笔推荐

如今&#xff0c;许多人都喜欢用IPAD来学习记录&#xff0c;或是安静地作画。很多ipad的用户&#xff0c;都很重视它的实用性&#xff0c;因为他们发现&#xff0c;如果有一款功能不错的电容笔来搭配ipad&#xff0c;那么ipad的实用性就会得到极大的提高。事实上&#xff0c;如…

开发 Chrome 扩展程序的利弊

作为一名软件开发人员,您总是希望从事能够提高您的技术技能并赚钱的项目。有什么比开发现金流 chrome 扩展程序更好的方法呢? 在本文中,我将从软件开发人员的角度概述开发 chrome 扩展程序的一些优点和缺点。 开发 Chrome 扩展程序的好处 Chrome 扩展程序是软件开发人员接…

基于遗传算法与神经网络的测井预测(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【序列召回推荐】(task4)多兴趣召回MIND模型

note Hinton在2011年提出的capsule network&#xff0c;通过EM期望值最大化算法&#xff0c;用动态路由代替反向传播进行更新参数&#xff0c;学习不同capsule之间的连接权重&#xff0c;实现比CNN更优秀的空间关系建模效果&#xff08;CNN可能对同一个图像的旋转版本识别错误…

Java笔记(十四)

文献种类&#xff1a;专题技术总结文献 开发工具与关键技术&#xff1a; IntelliJ IDEA、Java 语言 作者&#xff1a; 方建恒 年级&#xff1a; 2020 撰写时间&#xff1a; 2022 年 11 月 28 日 Java笔记(十四) 今天我给大家继续分享一下我的Java笔记&#xff0c; 我们继续来…