SpringIOC之创建Bean的核心方法doGetBean
概述
面向资源(XML、Properties)、面向注解定义的 Bean 是如何被解析成 BeanDefinition(Bean 的“前身”),并保存至 BeanDefinitionRegistry 注册中心里面,实际也是通过 ConcurrentHashMap 进行保存。
Spring 底层 IoC 容器 DefaultListableBeanFactory,实现了 BeanFactory 和 BeanDefinitionRegistry 接口,这个时候它处于“就绪状态”,当我们显示或者隐式地调用 getBean(...) 方法时,会触发加载 Bean 阶段,获取对应的 Bean。在该方法中,如果是单例模式会先从缓存中获取,已有则直接返回,没有则根据 BeanDefinition 开始创建这个 Bean。
主体流程:getBean doGetBean createBean doCreateBean createBeanInstance、instantiate、populateBean、initializeBean、registerDisposableBeanIfNecessary(注册销毁方法)
BeanFactory 体系结构
下来熟悉下Sprig容器BeanFactory的体系

org.springframework.beans.factory.BeanFactory,Spring IoC 容器最基础的接口,提供依赖查找单个 Bean 的功能
org.springframework.beans.factory.ListableBeanFactory,继承 BeanFactory 接口,提供依赖查找多个 Bean 的功能
org.springframework.beans.factory.HierarchicalBeanFactory,继承 BeanFactory 接口,提供获取父 BeanFactory 的功能,具有层次性
org.springframework.beans.factory.config.ConfigurableBeanFactory,继承 HierarchicalBeanFactory 接口,提供可操作内部相关组件的功能,具有可配置性
org.springframework.beans.factory.config.AutowireCapableBeanFactory,继承 BeanFactory 接口,提供可注入的功能,支持依赖注入
org.springframework.beans.factory.config.ConfigurableListableBeanFactory,继承上面所有接口,综合所有特性,还提供可提前初始化所有单例 Bean 的功能
org.springframework.beans.factory.support.DefaultListableBeanFactory,Spring 底层 IoC 容器,依赖注入的底层实现
getBean(String name) 方法,根据名称获取 Bean,当然还有许多重载方法
最终都会调用
doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) 方法
下面是编程方法获取Bean对象的方法
// 创建 BeanFactory 容器DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);// XML 配置文件 ClassPath 路径String location = "classpath:dependency-lookup-context.xml";// 加载配置int beanDefinitionsCount = reader.loadBeanDefinitions(location);System.out.println("Bean 定义加载的数量:" + beanDefinitionsCount);// 依赖查找System.out.println(beanFactory.getBean("user","1","jack2"));按照这个代码调试整理成下图的流程图
下图是关于doGetBean 方法这一层的执行逻辑。其他的核心方法后面在更新文章。


总结
可以看到这个方法加载 Bean 的过程中,会先从缓存中获取单例模式的 Bean;
不管是从缓存中获取的还是新创建的,都会进行处理,如果是 FactoryBean 类型则调用其 getObject() 获取目标对象;
BeanFactory 可能有父容器,如果当前容器找不到 BeanDefinition 则会尝试让父容器创建;
创建 Bean 的任务交由 AbstractAutowireCapableBeanFactory 去完成;
如果获取到的 Bean 不是我们想要类型,会通过类型转换机制转换成目标类型
获取 beanName
从缓存中获取单例 Bean
FactoryBean 的处理
非单例模式依赖检查
BeanFactory 层次性加载 Bean 策略
将 beanName 标记为已创建
获取 RootBeanDefinition
依赖 Bean 的处理
不同作用域的 Bean 的创建
单例模式
多例模式
其他模式

过程如下:
从当前容器获取该模式的 Scope 对象 scope,不存在则抛出异常
从 scope 中获取 beanName 对应的对象(看你的具体实现),不存在则执行原型模式的四个步骤进行创建
想要自定义一个作用域,可以实现 org.springframework.beans.factory.config.Scope 接口,并往 Spring 应用上下文注册即可 这个也是一个拓展接口
类型转换

如果入参 requiredType 不为空,并且 Bean 不是该类型,则需要进行类型转换,过程如下:
通过类型转换机制,将 Bean 转换成 requiredType 类型,对 Spring 的类型转换机制参考 org.springframework.core.convert.support.DefaultConversionService
我们也可以基于此做拓展的。
转换后的 Bean 为空则抛出异常
返回类型转换后的 Bean 对象
归纳拓展
对 BeanFactory 接口的体系结构进行了分析,得知 DefaultListableBeanFactory 是 BeanFactory 的最底层实现,也就是 Spring 的底层 IoC 容器。接着分析了 AbstractBeanFactory 的 getBean(...) 方法,当我们显示或者隐式地调用这个方法时,会触发 Bean 的加载。上面对 Bean 的加载过程进行了分析。
不同作用域的 Bean 的创建,底层都会调用 AbstractAutowireCapableBeanFactory 的 createBean(...)方法进行创建,创建 Bean 的过程涉及到 Bean 生命周期的大部分阶段,例如实例化阶段、属性赋值阶段、Aware 接口回调阶段、初始化阶段都是在这个方法中完成的。
相关文章:
SpringIOC之创建Bean的核心方法doGetBean
概述面向资源(XML、Properties)、面向注解定义的 Bean 是如何被解析成 BeanDefinition(Bean 的“前身”),并保存至 BeanDefinitionRegistry 注册中心里面,实际也是通过 ConcurrentHashMap 进行保存。Spring…...
docker快速部署xxjob2.3.0-SpringBoot快速集成示例
xxjob 2.3.0 部署 参考资料 docker安装xxl-job-admin步骤_JEECG低代码平台的技术博客_51CTO博客 run前准备 1 新建数据库 xxl_job 2 建表sql(可以直接使) https://github.com/xuxueli/xxl-job/blob/master/doc/db/tables_xxl_job.sql建库sql # # XXL-JOB v2.4.0-SNAPSHOT…...
项目管理的前路,前辈能给一些意见吗?
什么是项目管理?关于项目管理的解释主要是基于国际项目管理三大体系不同的解释及本领域权威专家的解释!!!! 项目管理就是以项目为对象的系统管理方法,通过一个临时性的、专门的柔性组织,对项目进行高效率的计划、组织、指导和控制,…...
省钱的年轻人,钱包被折扣店钻了空子
【潮汐商业评论/原创】过年期间,除了商场超市,小区附近的折扣店成了Amy经常光顾的对象。用Amy的话来说,“跟附近超市比价格,跟大卖场比距离,综合下来折扣店就是我随时购物的不二选择。”从Amy的话里,我们可…...
【华为OD机试真题 js、python】优选核酸检测点、寻找核酸检测点【2022 Q4 100分】
代码请进行一定修改后使用,提供有js、python两种语言 题目描述 张三要去外地出差,需要做核酸,需要在指定时间点前做完核酸,请帮他找到满足条件的 核酸检测只点。 给出一组核酸检测点的距离和每个核酸检测点当前的人数给出张三要去做核酸的出发时间 出发时间是10分钟的倍数…...
【MySQL】MySQL 8.0 新特性之 - 公用表表达式(CTE)
MySQL 8.0 新特性之 - 公用表表达式(CTE)1. 公用表表达式(CTE) - WITH 介绍1.1 公用表表表达式1.1.1 什么是公用表表达式1.1.2 CTE 语法1.1.3 CTE示例1.3 递归 CTE1.3.1 递归 CTE 简介1.3.2 递归成员限制1.3.3 递归 CTE 示例1.3.4…...
基础面试题:C++中如何理解const修饰符
面试题目:1、题 int i10; const int*p &i; int *const* p &i; const在不同位置有什么不 同 2、const 修饰类成员变量是有什么特殊要求 3、const 修饰类成员函数会发什么 4、const 对象有什么意义 目录 前言 一、const的意义 二、const使用规则 1.初始化…...
在RT-Thread STM32F407平台下配置SPI flash为U盘
记录下SPI Flash U盘实现过程中踩过的坑,与您分享。前提条件是,需要先将SPI Flash 配置到elm fal文件系统,并挂载成功。如下图然后开始配置USB1,在CubeMX,选择SUB_OTG_FS2 选择USB Device3,确认USB时钟为48…...
数据存储技术复习(二)未完
module3存储是数据中心内的核心元素。请说明常用的存储选项及其特点。磁盘驱动器:具有很大的存储容量,随机读/写访问闪存驱动器:使用半导体介质,提供高性能,低功耗2.若某磁盘驱动器显示每个磁道有八个扇区&…...
使用 QuTrunk+Amazon Deep Learning AMI(TensorFlow2)构建量子神经网络
量子神经网络是基于量子力学原理的计算神经网络模型。1995年,Subhash Kak 和 Ron Chrisley 独立发表了关于量子神经计算的第一个想法,他们致力于量子思维理论,认为量子效应在认知功能中起作用。然而,量子神经网络的典型研究涉及将…...
python selenium浏览器复用技术
使用selenium 做web自动化的时候,经常会遇到这样一种需求,是否可以在已经打开的浏览器基础上继续运行自动化脚本? 这样前面的验证码登录可以手工点过去,后面页面使用脚本继续执行,这样可以解决很大的一个痛点。 命令行…...
第二章:创建虚拟机
创建Windows server:首先第一步就是打开我们的vm,然后找到上一章讲的主页图标创建新的虚拟机。点击这上面类似的,然后转站。博文地址:https://blog.csdn.net/ryduijftgvhj/article/details/127934939?spm1001.2014.3001.5502视频…...
码上【call,apply,bind】的手写
一、call (1)官方用法 call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。 语法:function.call(要绑定的this值,参数,参数,…)。不一定这些参数都需要,这些参数都…...
代谢组学Nature子刊!抑郁症居然“男女有别”,脑膜淋巴管起关键作用!
文章标题:A functional role of meningeal lymphatics in sex difference of stress susceptibility in mice 发表期刊:Nature Communications 影响因子:17.694 发表时间:2022年8月 作者单位:中山大学中山医学院 …...
nacos配置中心搭建
网站每次更新版本都有短暂暂停,影响用户使用,返回经常不可用,需要改进 需要实现高可用,搭建负载均衡,实现jenkinsnacos不停机部署 nacos搭建预备环境准备 64 bit OS,支持 Linux/Unix/Mac/Windows&#x…...
uni-app低成本封装一个取色器组件
在uni-ui中找不到对应的工具 后面想想也是 移动端取色干什么? 没办法 也挂不住特殊需求 因为去应用市场下载 这总东西 又不是很有必要 那么 下面这个组件或许能解决您的烦恼 <template><view class"content"><view class"dialog&…...
APP 怎么免费接入 MobPush
1、获取 AppKey 申请 Appkey 的流程,请点击 http://bbs.mob.com/thread-8212-1-1.html?fromuid70819 2、下载 SDK 下载解压后,如下图: 目录结构 (1)Sample:演示Demo。(2)SDK&am…...
XGBoost
目录 1.XGBoost推导示意图 2.分裂节点算法 Weighted Quantile Sketch 3.对缺失值得处理 1.XGBoost推导示意图 XGBoost有两个很不错得典型算法,分别是用来进行分裂节点选择和缺失值处理 2.分裂节点算法 Weighted Quantile Sketch 对于特征切点点得选择ÿ…...
你是什么时候从轻视到高看软件测试的?
刚开始学软件测试很轻视,因为我那时很无知,这也是那时绝大多数人员的心态,那时中国最讲究“编程才是硬道理”。 如今却非常热爱软件测试,包括软件测试工具,方法,理论,技术。因为我在3年的测试工…...
基于ssm的航空售票系统
博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经从做了六年的毕业设计程序开发,开发过上千套毕业设计程序,没有什么华丽的语言…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
