Spring揭秘:BeanDefinitionRegistry应用场景及实现原理!

Spring揭秘:BeanDefinitionRegistry应用场景及实现原理! - 程序员古德

内容概要

BeanDefinitionRegistry接口提供了灵活且强大的Bean定义管理能力,通过该接口,开发者可以动态地注册、检索和移除Bean定义,使得Spring容器在应对复杂应用场景时更加游刃有余,增强了Spring容器的可扩展性和动态性,为开发者带来了更大的灵活性和控制力。

核心概念

它能用来干啥?

BeanDefinitionRegistry接口负责注册和管理Bean的定义信息,模拟一个业务案例来说明BeanDefinitionRegistry接口的作用。

假设,有一家大型餐厅,餐厅里有各种各样的员工,包括厨师、服务员、清洁工等,每个员工都有自己的职责和技能要求,餐厅的运营离不开这些员工的协同工作。

在这里,员工就相当于Spring框架中的Bean,而员工的职责和技能要求则对应Bean的定义信息,BeanDefinitionRegistry就像是餐厅的员工信息管理系统。

当招聘新员工时,会将他们的信息(姓名、职位、技能等)录入到这个系统中,同样地,在Spring框架中,当定义一个Bean时,Spring会将这个Bean的定义信息注册到BeanDefinitionRegistry中。

使用场景

  1. 员工招聘与注册:当餐厅需要招聘新员工时,会通过招聘流程确定员工的职位和技能要求,然后将这些信息录入到员工信息管理系统中,在Spring中,这相当于定义一个新的Bean,并将其注册到BeanDefinitionRegistry中。
  2. 员工信息查询与调度:当餐厅有工作任务需要完成时,会根据任务的要求,从员工信息管理系统中查询具备相应技能的员工,并安排他们执行任务,在Spring中,这相当于根据依赖关系从BeanDefinitionRegistry中查找并创建Bean的实例。
  3. 员工信息更新与维护:随着餐厅的运营,员工的职责或技能要求可能会发生变化,会及时更新员工信息管理系统中的信息,以确保信息的准确性,在Spring中,如果Bean的定义发生变化(例如,通过修改配置文件或注解),BeanDefinitionRegistry中的信息也会相应更新。

它有哪些特性?

BeanDefinitionRegistry接口主要用于解决Spring IoC容器中Bean定义信息的注册、存储和管理相关的技术问题。

BeanDefinitionRegistry接口提供了向Spring IoC容器注册Bean定义信息的方法,允许开发者在运行时动态地向容器中添加或修改Bean的定义。

BeanDefinitionRegistry可以解决如下类似的技术问题:

  1. Bean定义的注册:在Spring中,Bean的定义通常以配置文件(如XML)或注解的形式存在,BeanDefinitionRegistry提供了注册这些定义的方法,使得Spring IoC容器能够在运行时知道如何创建和管理这些Bean的实例。
  2. Bean定义的存储BeanDefinitionRegistry内部维护了一个用于存储Bean定义的注册表,这个注册表能够高效地存储和检索Bean的定义信息,从而支持Spring IoC容器的依赖注入和自动装配功能。
  3. Bean定义的动态管理:通过BeanDefinitionRegistry,开发者可以在运行时动态地添加、修改或删除Bean的定义。
  4. 支持多种配置方式BeanDefinitionRegistry与Spring的配置机制紧密结合,支持基于XML、注解、Java配置类等多种配置方式。
  5. 促进模块化和可扩展性:通过将Bean定义的注册和管理逻辑封装在BeanDefinitionRegistry中,Spring框架实现了模块化和可扩展性。开发者可以编写自己的Bean定义注册逻辑,并将其集成到Spring IoC容器中,从而扩展容器的功能。

代码案例

下面代码演示如何使用BeanDefinitionRegistry接口,并通过Spring IoC容器获取该bean的实例,如下代码:

package com.example.demo;  public class SimpleService {  public void doSomething() {  System.out.println("Doing something in SimpleService");  }  
}

创建一个BeanDefinitionRegistryPostProcessor来注册这个服务类的bean定义:

package com.example.demo;  import org.springframework.beans.BeansException;  
import org.springframework.beans.factory.config.BeanDefinition;  
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;  
import org.springframework.beans.factory.support.BeanDefinitionRegistry;  
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;  
import org.springframework.beans.factory.support.GenericBeanDefinition;  public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {  @Override  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {  // 创建bean定义  GenericBeanDefinition beanDefinition = new GenericBeanDefinition();  // 设置bean的类  beanDefinition.setBeanClassName("com.example.demo.SimpleService");  // 注册bean定义  registry.registerBeanDefinition("simpleService", beanDefinition);  }  @Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {  // 这里可以进行其他的BeanFactory后处理,但不是必须的  }  
}

然后,配置Spring来使用的CustomBeanDefinitionRegistryPostProcessor

package com.example.demo;  import org.springframework.context.annotation.AnnotationConfigApplicationContext;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  @Configuration  
public class AppConfig {  @Bean  public CustomBeanDefinitionRegistryPostProcessor customBeanDefinitionRegistryPostProcessor() {  return new CustomBeanDefinitionRegistryPostProcessor();  }  
}

最后,写一个客户端调用代码来启动Spring应用并获取注册的bean实例:

package com.example.demo;  import org.springframework.context.ConfigurableApplicationContext;  public class ClientApp {  public static void main(String[] args) {  // 创建应用上下文  ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);  // 从上下文中获取注册的bean  SimpleService simpleService = context.getBean(SimpleService.class);  // 调用bean的方法  simpleService.doSomething();  // 关闭应用上下文  context.close();  }  
}

当运行ClientAppmain方法时,会在控制台上看到输出:“Doing something in SimpleService”

核心API

BeanDefinitionRegistry接口是Spring IoC容器的一部分,它负责管理和维护Bean定义(BeanDefinition)。

BeanDefinition是Spring用来描述系统中Bean的元数据,包括Bean的类名、作用域、初始化方法、属性等信息。BeanDefinitionRegistry接口提供了一系列方法来注册、检索和删除这些Bean定义。

以下是BeanDefinitionRegistry接口中主要方法的含义:

  1. void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;

    这个方法用于注册一个Bean定义。它接受一个Bean名称(beanName)和一个对应的Bean定义(beanDefinition)。如果注册过程中发生错误,比如Bean名称已经存在,它会抛出BeanDefinitionStoreException异常。

  2. void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    这个方法用于从注册表中移除一个已经注册的Bean定义。它接受一个Bean名称作为参数。如果Bean定义不存在,它会抛出NoSuchBeanDefinitionException异常。

  3. BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    这个方法用于根据Bean名称检索一个Bean定义。如果找不到对应的Bean定义,它会抛出NoSuchBeanDefinitionException异常。

  4. boolean containsBeanDefinition(String beanName);

    这个方法用于检查注册表中是否包含指定名称的Bean定义。如果包含,返回true;否则返回false

  5. String[] getBeanDefinitionNames();

    这个方法返回注册表中所有Bean定义的名称数组。

  6. int getBeanDefinitionCount();

    这个方法返回注册表中Bean定义的数量。

  7. boolean isBeanNameInUse(String beanName);

    这个方法检查给定的Bean名称是否已经被使用。如果已经被使用,返回true;否则返回false。这个方法通常用于在注册新的Bean定义之前检查名称是否冲突。

技术原理

BeanDefinitionRegistry是Spring框架中用于注册、保存和管理BeanDefinition的接口,BeanDefinition是Spring用来描述系统中Bean的配置信息的接口,包括Bean的类名、作用域、属性、依赖等信息。

BeanDefinitionRegistry接口的实现类通常会将BeanDefinition存储在一个Map结构的数据集中,以便于根据Bean的名称快速查找对应的BeanDefinition

在Spring框架中,DefaultListableBeanFactoryBeanDefinitionRegistry接口的一个典型实现。

DefaultListableBeanFactory内部使用一个ConcurrentHashMap来存储BeanDefinition,从而保证了线程安全。

当调用registerBeanDefinition方法时,DefaultListableBeanFactory会首先检查传入的Bean名称是否已经被使用,如果已经被使用,则会抛出一个异常。

然后,它会将BeanDefinition添加到内部的ConcurrentHashMap中,同时,DefaultListableBeanFactory还会处理一些其他的逻辑,比如对BeanDefinition进行合并、解析等。

当调用getBeanDefinition方法时,DefaultListableBeanFactory会直接从内部的ConcurrentHashMap中根据Bean的名称查找对应的BeanDefinition

当调用removeBeanDefinition方法时,DefaultListableBeanFactory会从内部的ConcurrentHashMap中移除对应的BeanDefinition

BeanDefinitionRegistry接口的实现原理就是通过一个Map结构的数据集来存储和管理BeanDefinition,实际过程中可能会根据需求进行一些额外的处理,比如合并、解析等,但是,基本的思路就是通过Map结构来实现快速查找和存储。

注意:BeanDefinitionRegistry只是用于存储和管理BeanDefinition,并不负责Bean的实例化和依赖注入,这些工作是由Spring的其他部分(比如BeanFactoryApplicationContext)来完成的,当需要实例化一个Bean时,Spring会根据BeanDefinition中的信息来创建Bean的实例,并进行依赖注入。

核心总结

Spring揭秘:BeanDefinitionRegistry应用场景及实现原理! - 程序员古德

BeanDefinitionRegistry接口使得开发者能够灵活地注册、检索和管理Bean定义。

它提供了强大的Bean定义管理能力,支持动态地添加或移除Bean,使得Spring容器更加灵活和可扩展。

但是,直接操作BeanDefinitionRegistry需要对Spring有一定的理解,对初学者可能较为晦涩,难度较高,且不当使用可能导致容器状态混乱。

建议在使用时尽量通过Spring提供的高级抽象来管理Bean,除非确实需要直接操作底层的Bean定义。

关注我,每天学习互联网编程技术 - 程序员古德

END!
END!
END!

往期回顾

精品文章

Spring揭秘:@import注解应用场景及实现原理!

Java并发基础:原子类之AtomicMarkableReference全面解析!

Java并发基础:concurrent Flow API全面解析

Java并发基础:CopyOnWriteArraySet全面解析

Java并发基础:ConcurrentSkipListMap全面解析

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

哪里下载Mac上最全面的系统清理工具,CleanMyMac X4.15中文版永久版资源啊

哪里下载Mac上最全面的系统清理工具,CleanMyMac X4.15中文版永久版资源啊,CleanMyMac X4.15中文版是一款全面的Mac系统优化工具。它能够扫描、检测并清理不需要的文件和应用程序,优化内存使用和磁盘空间,提高Mac的性能表现。此外&…

基于Springboot+Layui餐厅点餐系统

一、项目背景 在互联网经济飞速发展的时代,网络化企业管理也在其带领下快速兴起,开发一款自主点餐系统会受到众多商家的青睐。现如今市场上的人力资源价格是非常高昂的,一款自主点餐系统可以减少餐厅的人力开销,将服务员从繁忙的…

传输请求(同服务器不同Client 不同服务器)

Landscape: 1. 同服务器不同Client间传输 100配置完需要在UT环境- DEV200测试的场合: 100生成的传输请求无需释放,直接在DEV200 Tcode SCC1接收即可(S4 hana: SCC1N)输入传输请求号,指定目标…

08 |「Fragment 」

前言 实践是最好的学习方式,技术也如此。 文章目录 前言一、简介1、是什么2、为什么要有 Fragment3. Fragment 详细解释 二、Fragment 与 Activity 的直观理解三、Fragment 的创建1、Fragment 的创建方式2、Fragment 的增删替查1) 替换(常见&…

Linux - 进程控制

1、进程创建 1.1、fork函数初识 在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程&#xff1b; #include <unistd.h> pid_t fork(void); 返回值&#xff1a;自进程中返回0&#xff0c;父进…

融资项目——OpenFeign的降级与熔断

当一个微服务调用其他微服务时&#xff0c;如果被调用的微服务因各种原因无法在规定时间内提供服务&#xff0c;则可以直接使用本地的服务作为备选&#xff0c;即进行降级熔断。 如之前所提到的微服务为例&#xff1a; 如果希望实现降级熔断&#xff0c;可以在本地创建一个实现…

Spring事务注解@Transactional的流程和源码分析

Spring事务简介 Spring事务有两种方式&#xff1a; 编程式事务&#xff1a;编程式事务通常使用编程式事务管理API实现&#xff0c;比如Spring提供的PlatformTransactionManager接口&#xff0c;使用它操控事务。声明式事务&#xff1a;注解式事务使用AOP&#xff08;面向切面…

【C++从0到王者】第五十站:B树

文章目录 一、内查找与外查找1.内查找2.外查找 二、B树概念三、B树的插入1.B树的插入分析2.B树插入总结3.插入代码实现4.B树满树和最空时候的对比5.B树的删除6.遍历B树7.B树的性能分析 一、内查找与外查找 1.内查找 像我们之前所用的在内存中的查找就是内查找 种类数据格式时…

IEEE754标准的c语言阐述,以及几个浮点数常量

很多年前&#xff0c;调研过浮点数与整数之间的双射问题&#xff1a; win7 intel x64 cpu vs2013 c语言浮点数精度失真问题 最近重新学习了一下IEEE754标准&#xff0c;也许实际还有很多深刻问题没有被揭示。 计算机程序设计艺术&#xff0c;据说这本书中也有讨论。 参考&…

如何将字体添加到 ONLYOFFICE 桌面编辑器8.0

作者&#xff1a;VincentYoung 为你写好的文字挑选一款好看的字体然而自带的字体列表却找不到你喜欢的怎么办&#xff1f;这只需要自己手动安装一款字体即可。这里教你在不同的桌面操作系统里的多种字体安装方法。 ONLYOFFICE 桌面编辑器 ONLYOFFICE 桌面编辑器是一款免费的办…

【C语言】终の指针(前篇)

个人主页点这里~ 指针初阶点这里~ 指针初阶2.0点这里~ 指针进阶点这里~ 终の指针 一、回调函数二、qsort函数1、整形比较2、结构数据比较①结构体②-> 的使用③结构数据比较 一、回调函数 回调函数就是⼀个通过函数指针调用的函数。 把一个函数的指针作为参数传递给另一…

@ResponseStatus

目录 概述&#xff1a; 用途&#xff1a; 参数&#xff1a; 注意事项&#xff1a; 自定义异常类&#xff1a; 底层原理&#xff1a; 概述&#xff1a; 在 Spring MVC 中&#xff0c;我们有很多方法来设置 HTTP 响应的状态码其中最直接的方法&#xff1a;使用 ResponseSt…

思维题(蓝桥杯 填空题 C++)

目录 题目一&#xff1a; ​编辑 代码&#xff1a; 题目二&#xff1a; 代码&#xff1a; 题目三&#xff1a; 代码&#xff1a; 题目四&#xff1a; 代码&#xff1a; 题目五&#xff1a; 代码&#xff1a; 题目六&#xff1a; 代码七&#xff1a; 题目八&#x…

分享关于如何解决系统设计问题的逐步框架

公司广泛采用系统设计面试&#xff0c;因为在这些面试中测试的沟通和解决问题的技能与软件工程师日常工作所需的技能相似。面试官的评估基于她如何分析一个模糊的问题以及如何逐步解决问题。测试的能力还包括她如何解释这个想法&#xff0c;与他人讨论&#xff0c;以及评估和优…

外包干了2年,技术退步明显

先说一下自己的情况&#xff0c;研究生&#xff0c;19年进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

docker部署若依项目

目录 目录 一、搭建局域 二、redis安装 1.创建目录 2. redis.conf修改 三、MySQL安装 1. 安装 2. 设置远程连接 3. 创建数据库 四、若依后端项目搭建 1. 切换到家目录 2. 上传jar包 3. 上传Dockerfile文件 4. 构建镜像 5. 运行容器 6. 查看运行情况 7. 测试(自己…

mysql bug( InnoDB: Error number 22),表突然不能读取

mysql bug&#xff08; InnoDB: Error number 22&#xff09;&#xff0c;表突然不能读取 bug最开始的bug&#xff1a;表突然不能读取关闭mysql容器&#xff0c;再次重启失败 解决方案不重建容器的几种可能措施重建容器重建如果懒得打命令或者忘记命令可能的run bug&#xff1a…

Hololens 2应用开发系列(2)——MRTK基础知识及配置文件配置(上)

Hololens 2应用开发系列&#xff08;2&#xff09;——MRTK基础知识及配置文件配置 一、前言二、MRTK基础知识2.1 MRTK概述2.2 MRTK运行逻辑2.3 MRTK配置文件介绍2.4 MRTK服务 三、配置文件使用3.1 总配置文件3.2 相机配置3.3 其他配置 参考文献 一、前言 在前面的文章中&…

【智能家居入门1之环境信息监测】(STM32、ONENET云平台、微信小程序、HTTP协议)

作为入门本篇只实现微信小程序接收下位机上传的数据&#xff0c;之后会持续发布如下项目&#xff1a;①可以实现微信小程序控制下位机动作&#xff0c;真正意义上的智能家居&#xff1b;②将网络通讯协议换成MQTT协议再实现上述功能&#xff0c;此时的服务器也不再是ONENET&…

一文看懂:组件化设计,B端系统不再重复造轮子。

B端组件化设计是指将企业级系统的界面设计和开发分解为独立的可复用组件&#xff0c;以实现系统的模块化和灵活性。 B端组件化设计的核心思想是将界面拆分成独立的功能组件&#xff0c;每个组件负责特定的功能或业务逻辑&#xff0c;可以独立开发、测试和维护&#xff0c;同时可…