觉得不错请按下图操作,掘友们,哈哈哈!!!
一:简述以及目录
Bean 的⽣命周期平常可能我们没太多去了解,但是在面试的时候这也是一个老生常谈的问题。
二:呕心沥血的流程图,绝对肝货
2.1 简化版
2.2 详细版
三:基础概念扫盲
2.1 什么是IOC
IOC全称是Inversion of Control,控制反转。它属于一种设计思想,由容器将设计好的对象交给容器控制,而非对象内部直接new。
四:执行流程分析
4.1 测试demo
1 | csharp复制代码package com.xiao.ma.yi; |
同时自定义一个处理器:
1 | typescript复制代码package com.xiao.ma.yi; |
XML配置文件:
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
测试执行入口:
1 | java复制代码 |
整个执行的结果如下:
- 1.调用构造方法: 早上好呀 我是一只快乐的小蚂蚁!
- 2.设置属性:我的名字叫快乐小蚂蚁
- 3.调用BeanNameAware#setBeanName方法: 我要起床了!!!
- 4.调用BeanFactoryAware#setBeanFactory方法:我穿好衣服了
- 5.BeanPostProcessor.postProcessBeforeInitialization方法:准备出门
- 6.InitializingBean#afterPropertiesSet方法:费了好大力气,找到了一块好吃的
- 7.自定义init方法:咯吱咯吱吃东西!!
- 8.BeanPostProcessor#postProcessAfterInitialization方法:终于吃饱了!
- XiaoMaYLifeBean:生活不就这样吗???
- 9.DisposableBean#destroy方法:晒晒太阳,准备回家了
- 10.自定义destroy方法:跑了一天好累,要休息了哦 !!!
是不是看到这里就很明显了,和前边Bean ⽣命周期流程图相互应。
4.2 我们能使用的扩展⽅法
通过上边我们可以以发现,在bean的整个声明周期中,我们在不同的时机可以进行拓展,基本上⼤致可以分为 4 类:
- 实现Aware 接⼝:让 我们的Bean 能拿到容器的⼀些资源,例如实现 BeanNameAware 的 setBeanName() 设置bean的名称, 实现BeanFactoryAware 的 setBeanFactory() 设置bean的工厂;
- 添加一些我们自定义的后处理器:进⾏⼀些前置和后置的处理,例如 BeanPostProcessor 的 postProcessBeforeInitialization() 和 postProcessAfterInitialization()在初始化前后做一些我们想要的操作;
- ⽣命周期接⼝:定义初始化⽅法和销毁⽅法的,例如 InitializingBean 的 afterPropertiesSet(),以及 DisposableBean 的 destroy();
- 配置⽣命周期⽅法:可以通过配置⽂件,或者configuration方式,⾃定义初始化和销毁⽅法,例如配置⽂件配置的 init() 和 destroyMethod()。
五:深入源码
5.1 代码入口
这里我们说的入口其实就是 AbstractApplicationContext#refresh 方法,这里主要列举我们bean声明周期中主要的点:
因为有一些系统bean也是通过这种方式创建,如上图,这里边有八个,所以这个地方,我们要把这些系统bean跳过去,找到我们的目标bean->XiaoMaYLifeBean.class
图中就到了我们自己定义的bean了,进入getBean() 方法。
进⼊ doGetBean(),从 getSingleton() 没有找到对象,进⼊创建 Bean 的逻辑。
开始创建XiaoMaYLifeBean 对象
进入createBean()方法:
5.2 bean的实例化
进⼊ doCreateBean() 后,我们走到 createBeanInstance() 调用处:
进入createBeanInstance() 方法:
接着进入instantiateBean() 方法:
进入instantiate() 方法:
进入BeanUtils.instantiateClass() 方法:
进入构造函数newInstance() 方法:
进入到XiaoMaYLifeBean的无参构造函数中:
到这里我们的bean就被实例化出来了,但是属性什么的还没填充,我们继续走回到:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中:
5.3 填充bean,属性赋值
进入populateBean()方法:
进⼊ populateBean() 后,执⾏ applyPropertyValues()
进⼊ applyPropertyValues(),执⾏ bw.setPropertyValues()
进⼊ processLocalProperty(),执⾏ ph.setValue()。
进入setValue() 方法:
进入invoke() 方法:
这时候就进入了我们自定义类的属性set方法:
到这⾥,populateBean() 就执⾏完毕,下⾯开始初始化 Bean。
5.4 初始化bean
这时候又回到了我们:AbstractAutowireCapableBeanFactory#doCreateBean,此时执行到了initializeBean()方法位置:
进入initializeBean()方法:
进入invokeAwareMethods()方法:
进入我们自己类设置beanName的方法:
回到 invokeAwareMethods():
进入我们自己类设置beanFactory的方法:
第一次回到 initializeBean(),执⾏下⾯逻辑。进入:applyBeanPostProcessorsBeforeInitialization() 方法:
找到我们的处理器:
执行我们自定义处理器的postProcessBeforeInitialization方法
第⼆次回到 initializeBean(),执⾏下⾯逻辑。
进入invokeInitMethods() 方法:
⾛进示例 XiaoMaYLifeBean 的⽅法,执⾏ afterPropertiesSet()。
返回 invokeInitMethods(),执⾏下⾯逻辑。
⾛进示例 XiaoMaYLifeBean 的⽅法,执⾏ init()。
第三次回到 initializeBean(),执⾏下⾯逻辑。
进入applyBeanPostProcessorsAfterInitialization()方法:
执行我们我们⾃⼰定义的后置处理⽅法postProcessAfterInitialization():
目前到这⾥,XiaoMaYLifeBean初始化的流程全部结束,其实主要流程都是围绕 initializeBean() 展开的。
六:bean的销毁
当 XiaoMaYLifeBean ⽣成后,后⾯就开始执⾏销毁操作,销毁的流程就⽐较简单。
入口close() 方法:
进入close() 方法:
进入doClose() 方法,看到我们标注的点:
这里就可以看到我们自己的close() 方法了:
⾛进示例 XiaoMaYLifeBean 的⽅法,执⾏ destroy()。
回到 destroy()方法,执⾏下⾯逻辑。
进入invokeCustomDestroyMethod() 方法:
结果完整出来了:
七:总要有总结
我们再回顾⼀下⼏个重要的⽅法:
- doCreateBean():这个是创建bean⼊⼝;
- createBeanInstance():就如方法名一样是⽤来初始化 Bean,⾥⾯会调⽤对象的构造⽅法,上边源码调试流程我们也有涉及;
- populateBean():填充对象属性依赖,以及成员变量初始化;
- initializeBean():这⾥⾯包含了 4 个⽅法,
- 先执⾏ aware 的 BeanNameAware比如设置beanName、BeanFactoryAware 接⼝ 设置beanFactory;
- 再执⾏ BeanPostProcessor bean的前置处理器接口;
- 然后执⾏ InitializingBean 接⼝,自己实现的 init()方法;
- 最后执⾏ BeanPostProcessor 的后置处理器接口。
- destory():先执⾏ DisposableBean 接⼝,再执⾏配置的 destroyMethod()。
相信通过这一篇bean的生命周期,我们对Springbean的生命周期有更深入的了解,其实里边也包含了AOP,以及循环依赖的相关东西了,在这个过程中其实对于我们无论是日常Spring相关的问题,还是面试时候的一些问题,如果熟读了一遍我相信很多都会在其中找到答案的。
整个系列目录:
本文正在参加「金石计划」
本文转载自: 掘金