【Spring 源码】 贯穿 Bean 生命周期的核心类之 AbstractAutowireCapableBeanFactory
🚀 作者主页: 有来技术
🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot
🌺 仓库主页: Gitee 💫 Github 💫 GitCode
💖 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请纠正!
目录
- 引言
- 核心方法:doCreateBean
- 1. 实例化 Bean
- 2. 属性注入
- 3. 初始化 Bean
- 4. 代理处理
- 总结
- 开源项目
引言
AbstractAutowireCapableBeanFactory 是 Spring 框架中至关重要的核心类之一,承担着整个 Bean 生命周期关键步骤的管理责任。其在 Bean 实例化、属性注入、初始化及代理处理等关键环节中发挥着关键作用,贯穿了整个 Bean 的声明周期。
核心方法:doCreateBean
深入研究 AbstractAutowireCapableBeanFactory 源码,将关注其中一个核心方法:doCreateBean。这个方法是贯穿 Bean 生命周期的纽带,涵盖了实例化、属性注入、初始化以及代理处理等关键任务。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.markAsPostProcessed();}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);exposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {throw bce;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);}}if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}
1. 实例化 Bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);
}
在这一步中,doCreateBean 方法首先尝试从单例缓存中获取 Bean 的包装实例,以支持单例模式。如果未找到,它将通过 createBeanInstance 方法进行实例化。
2. 属性注入
populateBean(beanName, mbd, instanceWrapper);
populateBean 方法负责将属性注入到 Bean 实例中,包括将依赖项注入到 Bean 中,以建立 Bean 之间的关系。
3. 初始化 Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
在这一步,initializeBean 方法被调用,负责执行 Bean 的初始化。这包括调用任何与 Bean 生命周期相关的回调方法,以及应用任何与 Bean 相关的后处理器。
4. 代理处理
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {// 处理代理,获取早期半成品对象exposedObject = earlySingletonReference;
}
在初始化之后,如果存在代理,通过从二级缓存获取早期半成品对象,实现代理的替换。这对于 AOP 等方面的处理非常关键。
总结
AbstractAutowireCapableBeanFactory 类集中了 Bean 生命周期中的关键步骤,包括实例化、属性注入、初始化以及代理处理。通过深入理解这个类及其核心方法,我们能更好地把握 Spring 框架中 Bean 的创建和管理机制,从而更有效地进行应用程序开发。
开源项目
- SpringCloud + Vue3 微服务商城
| Github | Gitee | |
|---|---|---|
| 后端 | youlai-mall 🍃 | youlai-mall 🍃 |
| 前端 | mall-admin🌺 | mall-admin 🌺 |
| 移动端 | mall-app 🍌 | mall-app 🍌 |
- SpringBoot 3+ Vue3 单体权限管理系统
| Github | Gitee | |
|---|---|---|
| 后端 | youlai-boot 🍃 | youlai-boot 🍃 |
| 前端 | vue3-element-admin 🌺 | vue3-element-admin 🌺 |
相关文章:
【Spring 源码】 贯穿 Bean 生命周期的核心类之 AbstractAutowireCapableBeanFactory
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…...
漏洞复现-某友UFIDA NC系统某接口未授权访问漏洞(附漏洞检测脚本)
免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…...
树莓派5安装opencv
1 建立虚拟环境 参考网站 https://www.piwheels.org/faq.html#venv 虚拟环境建立过程: To create a virtual environment: $ sudo apt install virtualenv python3-virtualenv -y $ virtualenv -p /usr/bin/python3 testpip sudo apt install virtualenv pytho…...
【测试开发】Python+Django实现接口测试工具
PythonDjango接口自动化 引言: 最近被几个公司实习生整自闭了,没有基础,想学自动化又不知道怎么去学,没有方向没有头绪,说白了其实就是学习过程中没有成就感,所以学不下去。出于各种花里胡哨的原因…...
从 MQTT、InfluxDB 将数据无缝接入 TDengine,接入功能与 Logstash 类似
利用 TDengine Enterprise 和 TDengine Cloud 的数据接入功能,我们现在能够将 MQTT、InfluxDB 中的数据通过规则无缝转换至 TDengine 中,在降低成本的同时,也为用户的数据转换工作提供了极大的便捷性。由于该功能在实现及使用上与 Logstash 类…...
友元c++
#include <iostream> #include <string> using namespace std; class Lovers//爱人关系,基类 { public: Lovers(string theName);// void kiss(Lovers *lover); void ask(Lovers *lover, string something); protected: string name; friend cla…...
java: 错误: 不支持发行版本 6
文章目录 背景一、问题二、问题排查三、最终解决方案 背景 我本地安装的jdk版本是jdk 17,在项目父工程中配置的版本是8版本,每次我启动项目时都会报错。 一、问题 二、问题排查 首先我排查了父工程pom.xml中的配置,配置的是8版本࿰…...
qml刷新C++中的QImage图像
第一步:重写QQuickImageProvider类 #include <QQuickImageProvider>class CQuickImagePainter : public QQuickImageProvider { public:CQuickImagePainter();QImage requestImage(const QString&id, QSize *, const QSize &);QPixmap requestPixm…...
IJCAI 2024 International Joint Conference on Artificial Intelligence
目录 1、 重要1.1 官网:1.2 提交网址:1.3 模板 (latex & word) 2、 Call for Papers2.1 Important Dates2.2 Details 3、 注意事项4 New in 20245 Simplified procedure for resubmission information6、 Submission Process …...
使用Python Flask搭建Web问答应用程序并发布到公网远程访问
使用Python Flask搭建web问答应用程序框架,并发布到公网上访问 文章目录 使用Python Flask搭建web问答应用程序框架,并发布到公网上访问前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程…...
android 13.0 app应用安装白名单
1.概述 在13.0系统rom定制化开发中,客户需求要实现应用安装白名单功能,在白名单之中的应用可以安装,其他的app不准安装,实现一个 控制app安装的功能,这需要从app安装流程入手就可以实现功能 PMS就是负责管理app安装的,功能就添加在这里就可以了,接下来看具体实现这个功能…...
SSL证书HTTPS保护服务
SSL证书属于数字证书的其中一种,广泛用于https协议,从而可以让数据传输在加密前提下完成,确保HTTPS网络安全是申请SSL证书必要工作。 SSL证书是主要用于https是一种加密协议,仔细观察网站地址会发现目前主流的网址前面都会有http…...
快速认识什么是:Docker
Docker,一种可以将软件打包到容器中并在任何环境中可靠运行的工具。但什么是容器以及为什么需要容器呢?今天就来一起学快速入门一下Docker吧!希望本文对您有所帮助。 假设您使用 Cobol 构建了一个在某种奇怪风格的 Linux 上运行的应用程序。您…...
c语言青蛙跳台阶
"青蛙跳台阶"问题是一个经典的动态规划问题,经常被用来解释动态规划的基本概念。问题的描述是:假设一只青蛙可以跳上1级或2级台阶,如果有n级台阶,那么青蛙有多少种跳法。 在C语言中,我们可以使用动态规划来…...
IntelliJ IDEA 2023.3 最新版如何试用?IntelliJ IDEA 2023.3 最新版试用方法
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
Java参数校验详解:使用@Valid注解和自定义注解进行参数验证
很多时候我们需要使用不少if、else等等逻辑判断及验证,这样在进行一些重复的参数校验会很麻烦,且以后要维护也会吃力。 而这样就可以使用javax.validation。验证(Validation)常见的验证操作包括验证数据的类型、格式、长度、范围、…...
多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测
多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现BWO-CNN-B…...
C++ 中的引用
文章目录 C 引用的应用1. 修改函数中传递的参数2. 避免复制大型结构3. for 循环中修改所有对象4. for 循环中避免复制对象 References vs Pointers引用的限制使用引用的优点练习Quesition 1Question 2Question 3Question 4Question 5Question 6 如果一个变量被声明为引用&#…...
MQ-Det: Multi-modal Queried Object Detection in the Wild
首个支持视觉和文本查询的开放集目标检测方法 NeurIPS2023 文章:https://arxiv.org/abs/2305.18980 代码:https://github.com/YifanXu74/MQ-Det 主框图 摘要 这篇文章提出了MQ-Det,一种高效的架构和预训练策略,它利用文本描述的…...
HarmonyOS应用开发初体验
9月25日华为秋季全场景新品发布会上,余承东宣布,全面启动鸿蒙原生应用,HarmonyOS NEXT开发者预览版将在2024年第一季度面向开发者开放。 最近鸿蒙开发可谓是火得一塌糊涂,各大培训平台都开设了鸿蒙开发课程。美团发布了鸿蒙高级工…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
