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

Spring Bean 的生命周期到底是什么?

Bean 的生命周期,指的是一个对象在 Spring 容器中,从创建、初始化,到被使用,再到最终销毁所经历的完整过程。

这道题是面试高频题,但很多人备考时习惯去网上找帖子背图。

其实不需要死记硬背,把核心阶段理解透,自然能用自己的话讲清楚。

BeanFactory 接口的源码注释中明确说明,它的实现类应当支持标准的 Bean 生命周期接口,并给出了标准初始化方法及其顺序。

一、源码入口:从 refresh 到 doCreateBean

refresh()流程中,Bean 的创建最终会进入finishBeanFactoryInitialization()

这里会遍历容器中所有需要初始化的 Bean(Bean 名先被收集进beanNames集合),并依次调用getBean()完成实例化。

getBean()内部继续进入doGetBean()

当缓存中不存在目标 Bean 时,会进一步调用createBean(),最终来到真正负责创建对象的doCreateBean()

Spring 源码中很多以 do 开头的方法承担核心执行逻辑,分析源码时通常需要重点关注。

二、实例化:靠反射生成对象

createBeanInstance()的职责就是完成 Bean 实例化。

Spring 底层仍然采用 Java 反射创建对象,本质流程与手写反射一致:

先获取Class对象,再获取构造器,最后通过反射调用构造方法生成实例。

实际代码中多数是无参构造,因此会通过getDeclaredConstructor()获取无参构造器,再交由BeanUtils工具类调用ctor.newInstance()完成实例化。

三、填充属性:populateBean

实例化完成后进入populateBean(),负责为 Bean 注入依赖和属性值。

属性注入完成后,Bean 还不能立即对外提供服务。

接下来进入初始化阶段,这也是 Bean 生命周期最重要的一部分。

四、初始化:Aware、后置处理器与初始化方法

初始化阶段首先处理各种 Aware 接口,例如BeanNameAwareBeanFactoryAware等。

Spring 会把容器相关信息注入 Bean,使其能够感知自身所处的运行环境。

随后执行BeanPostProcessor的前置方法postProcessBeforeInitialization()

之后进入初始化方法:

  • 如果 Bean 实现了InitializingBean接口,会调用afterPropertiesSet()。Bean 的创建全程由容器完成,若需要在属性装配完成后执行收尾逻辑,afterPropertiesSet()是常用的扩展点。
  • 如果配置中指定了init-method,会执行对应的自定义初始化方法,不过这种方式相对少用。

最后执行BeanPostProcessor的后置方法postProcessAfterInitialization()

如果 Bean 需要增强,例如使用 AOP,这一步会返回代理对象,而不是最初创建的原始对象。

初始化方式使用方式推荐程度
InitializingBean实现接口,重写afterPropertiesSet()常用扩展点,属性装配后的收尾机会
init-method配置中指定自定义方法名相对少用

后置方法执行完毕,Bean 的创建流程就全部完成。

五、使用与销毁

初始化完成后,Bean 即可对外提供服务,通过getBean()获取使用。

容器关闭时,Bean 进入销毁阶段,销毁方式与初始化对应:

  • 如果 Bean 实现了DisposableBean接口,会调用destroy()方法,释放资源一类的收尾逻辑通常放在这里。
  • 如果配置中指定了destroy-method,会执行对应的自定义销毁方法,同样相对少用。

需要注意的是,容器只负责单例 Bean 的销毁,prototype 作用域的 Bean 交出实例后便不再归容器管理。


整个 Bean 生命周期可以归纳为下面八个阶段:

实例化(反射生成对象)→ 填充属性 → 调用 Aware 接口 → 执行 BeanPostProcessor 前置 → 初始化(afterPropertiesSet / init-method)→ 执行 BeanPostProcessor 后置(AOP 代理通常在此阶段生成)→ 使用 → 销毁。

http://www.cnnetsun.cn/news/3792549.html

相关文章:

  • 3分钟完成Blender 3MF插件安装:彻底告别STL格式局限
  • 如何快速上手DeepSeek-Coder-V2:AI编程助手的完整指南
  • 【AI Agent 独立开发】拒绝精神内耗:一个基于大模型的治愈系 微应用《小木的心屋》
  • 解决PowerShell Invoke-RestMethod SSL/TLS安全通道错误:从协议配置到系统级修复
  • 【翼型】风洞压力数据自动处理计算气动系数(Cp、Cl、Cd、Cm)(生成与XFIL和薄翼型理论的对比可视化)【含Matlab源码 15912期】含报告
  • 基于Hailo-8L与RK3588的边缘AI部署:YOLOv8姿态估计实战
  • 3步解决Android手机玩PC游戏的难题:Winlator完全配置指南
  • MusicFree插件终极指南:解锁全网免费音乐资源的秘密武器
  • 数控机床数据采集技术全解析:从FOCAS到PLC的工业物联网实践
  • 分布式事务反直觉坑位与避坑指南:2PC、TCC 与 Saga 模式的物理死锁剖析
  • 微信DAT文件在线解码工具:基于异或加密原理的纯前端图片还原方案
  • uni-app实现微信小程序车辆图片滑动查看方案
  • 威斯康星乳腺癌数据集:从特征工程到模型评估的完整机器学习实战
  • 企业级外卖系统架构实战:从微服务拆分到高并发订单处理
  • AlphaFold贝叶斯扰动框架解析:原子分辨率预测内在无序蛋白动态构象
  • 从TCG/TPM到Secure Boot:拆解现代计算设备的硬件可信启动链
  • B站缓存视频合并终极解决方案:Android平台轻松导出完整MP4视频
  • Flask生产环境部署实战:Gunicorn/uWSGI与Nginx架构详解
  • Linux基础学习(9)Lamp架构(3)
  • AI 电动保温瓶智能功率 覆盖加热驱动、电源管理与电机控制的核心选型方案
  • 从源码编译到生产部署:Nginx在Linux服务器上的深度安装与配置指南
  • 2026年必看!专业匹克球拍工厂推荐榜单大揭秘,不容错过!
  • Python元组核心特性与应用场景全解析:从不可变性到实战技巧
  • EUI-NEO-DX11:轻量级C++ GUI框架与现代DirectX 11渲染实践
  • 基于 Highcharts 树形矩阵图实现全国省份人口层级分布
  • 局部莫兰指数(LISA)原理、计算与可视化:空间热点探测全解析
  • 从零搭建RLCraft服务器:硬核生存模组联机部署与优化指南
  • 菲涅尔反射率:实时渲染中实现真实材质与边缘光效的核心技术
  • EasyExcel自适应列宽与行高实现:告别丑报表的专业解决方案
  • reTerminal DM开发板eMMC刷写Raspbian全攻略:告别SD卡不稳定性