当前位置: 首页 > news >正文

【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 微服务商城
GithubGitee
后端youlai-mall 🍃youlai-mall 🍃
前端mall-admin🌺mall-admin 🌺
移动端mall-app 🍌mall-app 🍌
  • SpringBoot 3+ Vue3 单体权限管理系统
GithubGitee
后端youlai-boot 🍃youlai-boot 🍃
前端vue3-element-admin 🌺vue3-element-admin 🌺

相关文章:

【Spring 源码】 贯穿 Bean 生命周期的核心类之 AbstractAutowireCapableBeanFactory

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…...

漏洞复现-某友UFIDA NC系统某接口未授权访问漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…...

树莓派5安装opencv

1 建立虚拟环境 参考网站 https://www.piwheels.org/faq.html#venv 虚拟环境建立过程&#xff1a; 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接口自动化 引言&#xff1a; 最近被几个公司实习生整自闭了&#xff0c;没有基础&#xff0c;想学自动化又不知道怎么去学&#xff0c;没有方向没有头绪&#xff0c;说白了其实就是学习过程中没有成就感&#xff0c;所以学不下去。出于各种花里胡哨的原因&#xf…...

从 MQTT、InfluxDB 将数据无缝接入 TDengine,接入功能与 Logstash 类似

利用 TDengine Enterprise 和 TDengine Cloud 的数据接入功能&#xff0c;我们现在能够将 MQTT、InfluxDB 中的数据通过规则无缝转换至 TDengine 中&#xff0c;在降低成本的同时&#xff0c;也为用户的数据转换工作提供了极大的便捷性。由于该功能在实现及使用上与 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&#xff0c;在项目父工程中配置的版本是8版本&#xff0c;每次我启动项目时都会报错。 一、问题 二、问题排查 首先我排查了父工程pom.xml中的配置&#xff0c;配置的是8版本&#xff0…...

qml刷新C++中的QImage图像

第一步&#xff1a;重写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 官网&#xff1a;1.2 提交网址&#xff1a;1.3 模板 &#xff08;latex & word&#xff09; 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问答应用程序框架&#xff0c;并发布到公网上访问 文章目录 使用Python Flask搭建web问答应用程序框架&#xff0c;并发布到公网上访问前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程…...

android 13.0 app应用安装白名单

1.概述 在13.0系统rom定制化开发中,客户需求要实现应用安装白名单功能,在白名单之中的应用可以安装,其他的app不准安装,实现一个 控制app安装的功能,这需要从app安装流程入手就可以实现功能 PMS就是负责管理app安装的,功能就添加在这里就可以了,接下来看具体实现这个功能…...

SSL证书HTTPS保护服务

SSL证书属于数字证书的其中一种&#xff0c;广泛用于https协议&#xff0c;从而可以让数据传输在加密前提下完成&#xff0c;确保HTTPS网络安全是申请SSL证书必要工作。 SSL证书是主要用于https是一种加密协议&#xff0c;仔细观察网站地址会发现目前主流的网址前面都会有http…...

快速认识什么是:Docker

Docker&#xff0c;一种可以将软件打包到容器中并在任何环境中可靠运行的工具。但什么是容器以及为什么需要容器呢&#xff1f;今天就来一起学快速入门一下Docker吧&#xff01;希望本文对您有所帮助。 假设您使用 Cobol 构建了一个在某种奇怪风格的 Linux 上运行的应用程序。您…...

c语言青蛙跳台阶

"青蛙跳台阶"问题是一个经典的动态规划问题&#xff0c;经常被用来解释动态规划的基本概念。问题的描述是&#xff1a;假设一只青蛙可以跳上1级或2级台阶&#xff0c;如果有n级台阶&#xff0c;那么青蛙有多少种跳法。 在C语言中&#xff0c;我们可以使用动态规划来…...

IntelliJ IDEA 2023.3 最新版如何试用?IntelliJ IDEA 2023.3 最新版试用方法

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

Java参数校验详解:使用@Valid注解和自定义注解进行参数验证

很多时候我们需要使用不少if、else等等逻辑判断及验证&#xff0c;这样在进行一些重复的参数校验会很麻烦&#xff0c;且以后要维护也会吃力。 而这样就可以使用javax.validation。验证&#xff08;Validation&#xff09;常见的验证操作包括验证数据的类型、格式、长度、范围、…...

多维时序 | 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 文章&#xff1a;https://arxiv.org/abs/2305.18980 代码&#xff1a;https://github.com/YifanXu74/MQ-Det 主框图 摘要 这篇文章提出了MQ-Det&#xff0c;一种高效的架构和预训练策略&#xff0c;它利用文本描述的…...

HarmonyOS应用开发初体验

9月25日华为秋季全场景新品发布会上&#xff0c;余承东宣布&#xff0c;全面启动鸿蒙原生应用&#xff0c;HarmonyOS NEXT开发者预览版将在2024年第一季度面向开发者开放。 最近鸿蒙开发可谓是火得一塌糊涂&#xff0c;各大培训平台都开设了鸿蒙开发课程。美团发布了鸿蒙高级工…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

从实验室到产业:IndexTTS 在六大核心场景的落地实践

一、内容创作&#xff1a;重构数字内容生产范式 在短视频创作领域&#xff0c;IndexTTS 的语音克隆技术彻底改变了配音流程。B 站 UP 主通过 5 秒参考音频即可克隆出郭老师音色&#xff0c;生成的 “各位吴彦祖们大家好” 语音相似度达 97%&#xff0c;单条视频播放量突破百万…...

HTML版英语学习系统

HTML版英语学习系统 这是一个完全免费、无需安装、功能完整的英语学习工具&#xff0c;使用HTML CSS JavaScript实现。 功能 文本朗读练习 - 输入英文文章&#xff0c;系统朗读帮助练习听力和发音&#xff0c;适合跟读练习&#xff0c;模仿学习&#xff1b;实时词典查询 - 双…...

华为云Flexus+DeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手

华为云FlexusDeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手 一、构建知识库问答助手引言二、构建知识库问答助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建知识库问答助手实战3.1 配置Dify环境3.2 创建知识库问答助手3.3 使用知…...