Spring Boot自定义Namespace
创始人
2024-02-23 10:18:11
0

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 文件,内容如下




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命名空间, 完成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 定义




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 对象*/@Overridepublic 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) {//beanDefinitionRootBeanDefinition beanDefinition = new RootBeanDefinition();beanDefinition.setBeanClass(Student.class);beanDefinition.setLazyInit(false);//beanDefinition.setScope();//解析idString id = element.getAttribute("id");beanDefinition.getPropertyValues().add("id", id);//解析namebeanDefinition.getPropertyValues().add("name",element.getAttribute("name"));//解析 agebeanDefinition.getPropertyValues().add("age",element.getAttribute("age"));//majorbeanDefinition.getPropertyValues().add("major",element.getAttribute("major"));parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);return beanDefinition;}
    }
    

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

测试验证

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









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

源码地址

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...