Spring DefaultListableBeanFactory源码分析

DefaultListableBeanFactory源码分析文章目录
一、概述
二、关键结构与存储

  • Bean定义的存储结构
  • ConcurrentHashMap的使用和意义
    三、核心功能解析
    四、总结
    DefaultListableBeanFactory源码分析

一、概述

DefaultListableBeanFactory 是 Spring 框架中的一个核心类,它继承自AbstractAutowireCapableBeanFactory类,实现了 ListableBeanFactory 接口,并提供了一些额外的方法用于注册和获取Bean的定义。该类提供了 Spring 应用上下文中的 bean 定义和实例的管理功能。它是 Spring 容器的基础,负责管理 bean 的生命周期、依赖注入等核心功能。

二、主要功能

  1. Bean 定义管理DefaultListableBeanFactory 存储了所有的 bean 定义,这些定义通常来自于 XML 配置文件、注解或其他配置方式。
  2. Bean 实例化:根据 bean 的定义,容器负责实例化它们。
  3. 依赖注入:容器负责自动装配 bean 之间的依赖关系。
  4. 生命周期管理:容器负责管理 bean 的生命周期,从创建到销毁。
  5. 事件发布:容器负责发布与 bean 相关的各种事件,如初始化、销毁等。

三、关键代码分析

  1. Bean 定义存储
private final Map<String, RootBeanDefinition> 
beanDefinitionMap = new ConcurrentHashMap<>(256);

这里使用了一个 ConcurrentHashMap 来存储所有的 bean 定义。键是 bean 的名称,值是 RootBeanDefinition 对象,它包含了 bean 的完整定义信息。
2. Bean 实例化

当需要实例化一个 bean 时,DefaultListableBeanFactory 会使用 getBean() 方法。这个方法首先检查请求的 bean 是否已经存在实例,如果存在则直接返回;如果不存在,它会调用 createBean() 方法来创建 bean 的实例。
3. 依赖注入

在创建 bean 的实例后,DefaultListableBeanFactory 会自动检测该 bean 的所有依赖项,并注入这些依赖。这个过程通过反射实现,利用了 Java 的 FieldMethod 类来访问和修改对象的属性。
4. 事件发布

当 bean 的生命周期发生变化时(如初始化、销毁等),DefaultListableBeanFactory 会发布相应的事件。这些事件会被注册的监听器捕获并处理。事件的发布通过 Spring 的事件机制实现,基于发布-订阅模式。
5. 其他关键方法

  • addBeanPostProcessor: 用于添加后处理器,可以在 bean 创建后对其进行进一步处理。
  • registerBeanDefinition: 用于注册一个新的 bean 定义。
  • removeBeanDefinition: 用于移除一个已注册的 bean 定义。
  • getBeanNamesForType: 根据给定的类型获取所有相关的 bean 名称。
  • getBeansOfType: 根据给定的类型获取所有相关的 bean 实例。
  • getAliases: 获取指定名称的所有别名。

四、总结

DefaultListableBeanFactory 是 Spring 框架中非常重要的一个类,它提供了基础的 bean 管理功能,使得开发者能够专注于业务逻辑而不是底层的bean 管理。通过对它的源码分析,我们可以深入了解 Spring 的核心工作原理,从而更好地利用这个框架来构建企业级应用。

下面是DefaultListableBeanFactory的精简源码:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {// 用于保存Bean定义的Mapprivate final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();// 用于保存Bean实例的Mapprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();// 用于保存Bean的作用域的Mapprivate final Map<String, Scope> scopes = new ConcurrentHashMap<>();// 用于保存Bean的后置处理器的Listprivate final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();// 用于保存Bean的初始化方法的Mapprivate final Map<String, String> initMethods = new ConcurrentHashMap<>();// 用于保存Bean的销毁方法的Mapprivate final Map<String, String> destroyMethods = new ConcurrentHashMap<>();// 用于保存Bean的销毁回调的Listprivate final List<Runnable> destroyCallbacks = new CopyOnWriteArrayList<>();// 用于保存Bean的依赖关系的Mapprivate final Map<String, Set<String>> dependentBeans = new ConcurrentHashMap<>();// 用于保存Bean的依赖关系反转的Mapprivate final Map<String, Set<String>> dependenciesForBean = new ConcurrentHashMap<>();// 用于保存Bean的别名的Mapprivate final Map<String, String> aliases = new ConcurrentHashMap<>();// 用于保存Bean的类型的Mapprivate final Map<String, Class<?>> types = new ConcurrentHashMap<>();// 用于保存Bean的标记的Listprivate final List<String> alreadyCreated = new CopyOnWriteArrayList<>();// 用于保存Bean的ClassLoaderprivate ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();// 用于保存Bean的属性编辑器的Mapprivate final Map<Class<?>, PropertyEditor> customEditors = new ConcurrentHashMap<>();// 用于保存Bean的TypeConverterprivate TypeConverter typeConverter;// ... 其他成员变量和方法省略 ...@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {Assert.notNull(beanName, "Bean name must not be null");Assert.notNull(beanDefinition, "BeanDefinition must not be null");if (containsBeanDefinition(beanName)) {throw new BeanDefinitionStoreException("Bean definition for bean '" + beanName + "' already exists");}beanDefinitionMap.put(beanName, beanDefinition);if (beanDefinition instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDefinition).hasBeanClass()) {Class<?> beanClass = ((AbstractBeanDefinition) beanDefinition).getBeanClass();types.put(beanName, beanClass);}if (beanDefinition instanceof AnnotatedBeanDefinition) {MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata();if (factoryMethodMetadata != null && beanDefinition instanceof AbstractBeanDefinition) {((AbstractBeanDefinition) beanDefinition).setResolvedFactoryMethod(factoryMethodMetadata);}}// 发布Bean定义注册事件if (hasBeanCreationStarted()) {// 如果容器已经开始创建Bean,则立即初始化该BeanfinishBeanFactoryInitialization();}}@Overridepublic BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {Assert.notNull(beanName, "Bean name must not be null");BeanDefinition bd = beanDefinitionMap.get(beanName);if (bd == null) {throw new NoSuchBeanDefinitionException(beanName);}return bd;}@Overridepublic boolean containsBeanDefinition(String beanName) {Assert.notNull(beanName, "Bean name must not be null");return beanDefinitionMap.containsKey(beanName);}// ... 其他方法省略 ...protected void processBeanDefinition(BeanDefinition beanDefinition) throws BeanDefinitionStoreException {if (beanDefinition instanceof AbstractBeanDefinition) {AbstractBeanDefinition abstractBeanDefinition = (AbstractBeanDefinition) beanDefinition;if (abstractBeanDefinition.hasBeanClass()) {if (!abstractBeanDefinition.isSynthetic()) {validateBeanDefinition(abstractBeanDefinition);}prepareMethodOverrides(abstractBeanDefinition);}}}// ... 其他方法省略 ...@Overrideprotected void initBeanWrapper(BeanWrapper bw) {bw.setConversionService(getConversionService());}@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {// 实例化BeanObject bean = resolveBeforeInstantiation(beanName, mbd);if (bean != null) {return bean;}return doCreateBean(beanName, mbd, args);}// ... 其他方法省略 ...}

以上是DefaultListableBeanFactory的源码核心部分。它主要通过使用Java的集合类来存储和管理Bean的定义、实例、作用域、后置处理器等信息。它实现了BeanDefinitionRegistry接口,可以注册和获取Bean的定义。它还继承自AbstractAutowireCapableBeanFactory类,提供了创建和初始化Bean的功能。

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

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

相关文章

阿里巴巴代码平台架构的演进之路

简介&#xff1a; 这事儿和伽利略有关。 代码平台的发展之路 相信很多做后端服务的同学在看到单机、读写分离、分片这些字眼一定不会觉得陌生。没错&#xff0c;代码服务在发展的开始阶段面临的问题和其他web服务大体一致&#xff0c;所以使用的解决方案也大体一致。 单机服务…

从工具到平台|默安科技研发安全一体化管理平台正式发布

作者|默安科技 数字化转型浪潮下&#xff0c;软件研发安全的重要性毋庸置疑。 据第三方权威调查&#xff0c;接近92%的已知安全漏洞发生在软件应用程序中&#xff0c;且应用中每1000行代码至少出现一个业务逻辑缺陷。 在近年来如火如荼的攻防演练中&#xff0c;应用程序成为…

如何避免 Go 命令行执行产生“孤儿”进程?

简介&#xff1a; 在 Go 程序当中&#xff0c;如果我们要执行命令时&#xff0c;通常会使用 exec.Command &#xff0c;也比较好用&#xff0c;通常状况下&#xff0c;可以达到我们的目的&#xff0c;如果我们逻辑当中&#xff0c;需要终止这个进程&#xff0c;则可以快速使用 …

边缘指示函数matlab,matlab图像处理——傅立叶变换边缘提取

第一部分 图像的傅立叶变换一、 实验目的1.了解图像变换的意义和手段&#xff1b;2. 熟悉傅里叶变换的基本性质&#xff1b;3. 熟练掌握FFT的方法及应用&#xff1b;4. 通过实验了解二维频谱的分布特点&#xff1b;5. 通过本实验掌握利用MATLAB编程实现数字图像的傅立叶变换。二…

杭州南江机器人现在是否量产_传亚马逊正开发家庭机器人,高约1米可移动

点击右上角关注我&#xff0c;成为科技圈最靓的仔&#xff01;智东西(公众号&#xff1a;zhidxcom)编 | 王颖 导语&#xff1a;据外媒报道&#xff0c;亚马逊计划今年推出一款可移动家庭机器人&#xff0c;高度约为1米&#xff0c;可通过语音控制。智东西7月15日消息&#xff0…

OpenYurt 联手 eKuiper,解决 IoT 场景下边缘流数据处理难题

简介&#xff1a; 云计算的出现促使物联网实现爆炸式增长。在设备规模和业务复杂度不断攀升的趋势之下&#xff0c;边缘计算因其能够将计算能力更靠近网络边缘和设备&#xff0c;从而带来云性能成本的降低&#xff0c;也在这波浪潮之下得到快速发展。 作者 | OpenYurt 社区 云…

OS2ATC 2021:开源协作,和而不同

12月26日由中科院软件所主办&#xff0c;清华大学、北京大学以及鉴释科技承办的第九届开源操作系统年度技术会议&#xff08;OS2ATC&#xff09;正式拉开序幕&#xff0c;百余位重量嘉宾莅临现场&#xff0c;围绕大会主题“开源协作&#xff0c;和而不同”共同探讨操作系统开源…

ChaosBlade:从混沌工程实验工具到混沌工程平台

简介&#xff1a; ChaosBlade 是阿里巴巴 2019 年开源的混沌工程项目&#xff0c;已加入到 CNCF Sandbox 中。起初包含面向多环境、多语言的混沌工程实验工具 chaosblade&#xff0c;到现在发展到面向多集群、多环境、多语言的混沌工程平台 chaosblade-box&#xff0c;平台支持…

python 按行写入_Python中将变量按行写入txt文本

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…

揭秘阿里云 RTS SDK 是如何实现直播降低延迟和卡顿

简介&#xff1a; RTS NetSDK是未来直播和通信一体化SDK的基石。在RTS NetSDK之上&#xff0c;加一个Multimedia Framework&#xff0c;以及QoS消息处理&#xff0c;就可以构成一个一体化SDK。这对于已经有自己的Framework的客户来说是个好消息&#xff0c;不需要为直播和通信分…

Forrester云原生开发者洞察白皮书,低代码概念缔造者又提出新的开发范式

简介&#xff1a; 云原生时代的到来为开发者群体带来了前所未有的机遇&#xff0c;让开发者可以更加专注业务价值创造与创新&#xff0c;并使得人人成为开发者成为现实。广大开发者如何转型成为云原生开发者&#xff1f;运维等专业人员在云原生时代如何避免边缘化的囧境&#x…

彻底理解内存泄漏,memory leak

作者 | 码农的荒岛求生来源 | 码农的荒岛求生内存申请就好比去停车场找停车位&#xff0c;找到停车位后你就可以把车停在这里。从这个类比看什么是内存泄漏呢&#xff1f;内存泄漏看上去是停车场的车辆只进不出导致最终找不到停车位&#xff0c;从程序员的角度看就是内存只申请…

动态后台获取_后台管理系统的权限以及vue处理权限的思路

一般来说&#xff0c;在&#xff08;后台&#xff09;管理系统&#xff08;最早的企业级的项目和网站的后台管理系统现在大部分人都叫后台管理系统&#xff09;中才会有权限之说。权限分为功能级权限和数据级权限。这篇文章主要谈论功能级权限。一、名词解释&#xff1a;权限的…

php文件遍历类,PHP 遍历文件夹及文件类及处理类

FindFile.class.php用于遍历目录文件/** 遍历文件夹及文件类* Date: 2013-03-21* Author: fdipzone* Ver: 1.0*/class FindFile{public $files array(); // 存储遍历的文件protected $maxdepth; // 搜寻深度,0表示没有限制/* 遍历文件及文件夹* param String $spath 文件夹路径…

ARMv9刷屏 —— 号称十年最大变革,Realm机密计算技术有什么亮点?

简介&#xff1a; 让我们看下ARMv9机密计算相关的新特性Realm。 ARMv9的新闻刷屏了。ARMv9号称十年以来最重大变革&#xff0c;因此让我们看下ARMv9中机密计算相关的新特性Realm。&#xff08;注&#xff1a;本文是对Introducing the Confidential Compute Architecture的部分翻…

JVM性能提升50%,聊一聊背后的秘密武器Alibaba Dragonwell

简介&#xff1a; 你要知道的关于Alibaba Dragonwell一些重要优化措施。 今年四月五日&#xff0c;阿里云开放了新一代ECS实例的邀测[1]&#xff0c;Alibaba Dragonwell也在新ECS上进行了极致的优化。相比于之前的dragonwell_11.0.8.3版本&#xff0c;即将发布的dragonwell_11.…

34 年了,“杀”不死的 Perl!

作者 | 祝涛 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;2021年12月18日&#xff0c;Perl迎来了自己34岁的生日。当程序员聊到Perl会聊些什么呢&#xff1f;在各大平台搜索Perl时&#xff0c;你会发现大家对Perl的态度呈现出一种两级分化的状态&#xff…

python的stack用法_Python numpy.stack函数方法的使用

numpy.stacknumpy.stack(arrays, axis0, outNone) [source]沿着新的轴连接数组序列。axis参数在结果的维度中指定新轴的索引。例如&#xff0c;如果axis0&#xff0c;它将是第一个维度;如果axis-1&#xff0c;它将是最后一个维度。1.10.0版中的新功能。参数 &#xff1a;a…

“不服跑个分?” 是噱头还是实力?

简介&#xff1a; Linux内核社区常常以跑分软件得分&#xff0c;来评价一个优化补丁的价值。让软件跑高分&#xff0c;就是实力的体现&#xff01; 一、背景&#xff1a;性能之战 “不服跑个分”已经沦为手机行业的调侃用语&#xff0c;但是实话实说&#xff0c;在操作系统领域…

Medusa 又一个 Shopify 的开源替代品!

作者 | Eason来源 | 程序员巴士Medusa是一个开源的headless商务引擎&#xff0c;具有速度快且可定制的优点。由于 Medusa 分为 3 个核心组件 - 公开的REST API headless商务部分、商店的前端以及admin面板 - 大家可以自由地整体使用该平台或者来适配设置电子商店。在本教程系列…