面试官:什么是Bean 生命周期?
Spring Bean 的生命周期面试时非常容易问这不前段时间就有个粉丝去字节面试因为不会回答这个问题一面都没有过。1. 基础知识1.1 什么是 IoC IoC控制反转想必大家都知道所谓的控制反转就是把 new 对象的权利交给容器所有的对象都被容器控制这就叫所谓的控制反转。IoC 很好地体现了面向对象设计法则之一 —— 好莱坞法则“别找我们我们找你”即由 IoC 容器帮对象找相应的依赖对象并注入而不是由对象主动去找。理解好 IoC 的关键是要明确 “谁控制谁控制什么为何是反转有反转就应该有正转了哪些方面反转了”。谁控制谁控制什么传统 Java SE 程序设计我们直接在对象内部通过 new 进行创建对象是程序主动去创建依赖对象。而 IoC 是由专门一个容器来创建这些对象即由 IoC 容器来控制对象的创建。谁控制谁当然是 IoC 容器控制了对象控制什么主要控制了外部资源获取不只是对象比如包括文件等。为何是反转哪些方面反转了有反转就有正转传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象也就是正转而反转则是由容器来帮忙创建及注入依赖对象。为何是反转因为由容器帮我们查找及注入依赖对象对象只是被动的接受依赖对象所以是反转哪些方面反转了依赖对象的获取被反转了。1.2 Bean 生命周期对 Prototype Bean 来说当用户 getBean 获得 Prototype Bean 的实例后IOC 容器就不再对当前实例进行管理而是把管理权交由用户此后再 getBean 生成的是新的实例。所以我们描述 Bean 的生命周期都是指的 Singleton Bean。Bean 生命周期过程实例化第 1 步实例化一个 Bean 对象属性赋值第 2 步为 Bean 设置相关属性和依赖初始化初始化的阶段的步骤比较多5、6 步是真正的初始化第 3、4 步为在初始化前执行第 7 步在初始化后执行初始化完成之后Bean 就可以被使用了销毁第 8~10 步第 8 步其实也可以算到销毁阶段但不是真正意义上的销毁而是先在使用前注册了销毁的相关调用接口为了后面第 9、10 步真正销毁 Bean 时再执行相应的方法。整个执行流程稍微有些抽象下面我们通过代码来演示执行流程。1.3 执行流程创建一个 LouzaiBean。public class LouzaiBean implements InitializingBean, BeanFactoryAware, BeanNameAware, DisposableBean { /** * 姓名 */ private String name; public LouzaiBean() { System.out.println(1.调用构造方法我出生了); } public String getName() { return name; } public void setName(String name) { this.name name; System.out.println(2.设置属性我的名字叫name); } Override public void setBeanName(String s) { System.out.println(3.调用BeanNameAware#setBeanName方法:我要上学了起了个学名); } Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println(4.调用BeanFactoryAware#setBeanFactory方法选好学校了); } Override public void afterPropertiesSet() throws Exception { System.out.println(6.InitializingBean#afterPropertiesSet方法入学登记); } public void init() { System.out.println(7.自定义init方法努力上学ing); } Override public void destroy() throws Exception { System.out.println(9.DisposableBean#destroy方法平淡的一生落幕了); } public void destroyMethod() { System.out.println(10.自定义destroy方法:睡了别想叫醒我); } public void work(){ System.out.println(Bean使用中工作只有对社会没有用的人才放假。。); } }自定义一个后处理器 MyBeanPostProcessor。public class MyBeanPostProcessor implements BeanPostProcessor { Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(5.BeanPostProcessor.postProcessBeforeInitialization方法到学校报名啦); return bean; } Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(8.BeanPostProcessor#postProcessAfterInitialization方法终于毕业拿到毕业证啦); return bean; } }applicationContext.xml 配置文件部分。bean namemyBeanPostProcessor classdemo.MyBeanPostProcessor / bean namelouzaiBean classdemo.LouzaiBean init-methodinit destroy-methoddestroyMethod property namename value楼仔 / /bean测试入口public class MyTest { public static void main(String[] args) { ApplicationContext context new ClassPathXmlApplicationContext(classpath:applicationContext.xml); LouzaiBean louzaiBean (LouzaiBean) context.getBean(louzaiBean); louzaiBean.work(); ((ClassPathXmlApplicationContext) context).destroy(); } }执行结果1.调用构造方法我出生了 2.设置属性我的名字叫楼仔 3.调用BeanNameAware#setBeanName方法:我要上学了起了个学名 4.调用BeanFactoryAware#setBeanFactory方法选好学校了 5.BeanPostProcessor.postProcessBeforeInitialization方法到学校报名啦 6.InitializingBean#afterPropertiesSet方法入学登记 7.自定义init方法努力上学ing 8.BeanPostProcessor#postProcessAfterInitialization方法终于毕业拿到毕业证啦 Bean使用中工作只有对社会没有用的人才放假。。 9.DisposableBean#destroy方法平淡的一生落幕了 10.自定义destroy方法:睡了别想叫醒我这个流程非常清晰Bean 生命周期流程图能完全对应起来。1.4 扩展方法我们发现整个生命周期有很多扩展过程大致可以分为 4 类Aware 接口让 Bean 能拿到容器的一些资源例如 BeanNameAware 的setBeanName()BeanFactoryAware 的setBeanFactory()后处理器进行一些前置和后置的处理例如 BeanPostProcessor 的postProcessBeforeInitialization()和postProcessAfterInitialization()生命周期接口定义初始化方法和销毁方法的例如 InitializingBean 的afterPropertiesSet()以及 DisposableBean 的destroy()配置生命周期方法可以通过配置文件自定义初始化和销毁方法例如配置文件配置的init()和destroyMethod()。2. 源码解读注意Spring 的版本是5.2.15.RELEASE否则和我的代码不一样上面的知识网上其实都有下面才是我们的重头戏让你跟着我走一遍代码流程。2.1 代码入口这里需要多跑几次把前面的 beanName 跳过去只看 louzaiBean。进入 doGetBean()从 getSingleton() 没有找到对象进入创建 Bean 的逻辑。2.2 实例化进入 doCreateBean() 后调用 createBeanInstance()。进入 createBeanInstance() 后调用 instantiateBean()。走进示例 LouzaiBean 的方法实例化 LouzaiBean。2.3 属性赋值再回到 doCreateBean()继续往后走进入 populateBean()。这个方法非常重要里面其实就是依赖注入的逻辑不过这个不是我们今天的重点大家如果对依赖注入和循环依赖感兴趣可以翻阅我之前的文章。进入 populateBean() 后执行 applyPropertyValues()进入 applyPropertyValues()执行 bw.setPropertyValues()进入 processLocalProperty()执行 ph.setValue()。走进示例 LouzaiBean 的方法给 LouzaiBean 赋值 name。到这里populateBean() 就执行完毕下面开始初始化 Bean。2.4 初始化我们继续回到 doCreateBean()往后执行 initializeBean()。走进示例 LouzaiBean 的方法给 LouzaiBean 设置 BeanName。回到 invokeAwareMethods()。走进示例 LouzaiBean 的方法给 LouzaiBean 设置 BeanFactory。第一次回到 initializeBean()执行下面逻辑。这里需要多循环几次找到 MyBeanPostProcessor 的策略方法。我们自己定义的后置处理方法。第二次回到 initializeBean()执行下面逻辑。走进示例 LouzaiBean 的方法执行 afterPropertiesSet()。返回 invokeInitMethods()执行下面逻辑。进入 invokeCustomInitMethod()执行下面逻辑。走进示例 LouzaiBean 的方法执行 init()。第三次回到 initializeBean()执行下面逻辑。我们自己定义的后置处理方法。到这里初始化的流程全部结束都是围绕 initializeBean() 展开。2.4 销毁当 louzaiBean 生成后后面开始执行销毁操作整个流程就比较简单。走进示例 LouzaiBean 的方法执行 destroy()。回到 destroy()执行下面逻辑。走进示例 LouzaiBean 的方法执行 destroyMethod()。到这里所有的流程全部结束文章详细描述所有的代码逻辑流转你可以完全根据上面的逻辑自己 debug 一遍。3. 写在最后我们再回顾一下几个重要的方法doCreateBean()这个是入口createBeanInstance()用来初始化 Bean里面会调用对象的构造方法populateBean()属性对象的依赖注入以及成员变量初始化initializeBean()里面有 4 个方法先执行 aware 的 BeanNameAware、BeanFactoryAware 接口再执行 BeanPostProcessor 前置接口然后执行 InitializingBean 接口以及配置的 init()最后执行 BeanPostProcessor 的后置接口。destory()先执行 DisposableBean 接口再执行配置的 destroyMethod()。对于 populateBean()里面的核心其实是对象的依赖注入这里也是常考的知识点

相关新闻

SQL 优化的 15 个小技巧,超实用!

SQL 优化的 15 个小技巧,超实用!

SQL 优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到。如果某天你负责的某个线上接口,出现了性能问题,需要做优化。那么你首先想到的很有可能是优化 SQL 语句,因为它的改造成…

2026/10/26 11:17:52 阅读更多 →
源码深度解析,Spring 如何解决循环依赖?

源码深度解析,Spring 如何解决循环依赖?

1. 基础知识1.1 什么是循环依赖 ?一个或多个对象之间存在直接或间接的依赖关系,这种依赖关系构成一个环形调用,有下面 3 种方式。我们看一个简单的 Demo,对标“情况 2”。Service public class Louzai1 {Autowiredprivate Louzai2…

2026/10/25 13:55:38 阅读更多 →
AIGC检测与优化工具千笔的技术原理与应用

AIGC检测与优化工具千笔的技术原理与应用

1. 项目背景与核心价值"千笔专业降AIGC智能体"这个工具名称本身就揭示了它的核心定位——这是一款面向学术场景的AIGC内容检测与优化工具。在当前AI生成内容(AIGC)爆发的时代,教育领域面临着前所未有的挑战:如何区分学生…

2026/10/25 16:58:33 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/25 22:36:10 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/26 5:00:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/26 3:16:46 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →