SpringBoot相关文章
生命周期
如果面试遇到这个问题的话,要先确定思路,第一反应应该围绕着一个核心状态转移流程。普通Java类-> BeanDefinition -> bean实例化-> 依赖注入-> bean初始化。
整个SpringBean的生命周期主要完成这几个状态的转变,按着具体的状态变化尽可能地用一些细节丰富自己的答案。
BeanDefinition
BeanDefinition是Spring提供的一个Bean对象的封装类,可以理解为一个创建Bean的前置对象,里面会存储一些bean的配置信息。如要加载bean的class信息、dependsOn信息(依赖某个类的加载),作用域等。
整个生命周期的第一步伴随着SpringBoot的启动流程,扫描整个classpath下所有标注对应注解的的类将其转换成BeanDefinition对象并存储对应元信息。
说了BeanDeinition就不得不清楚Spring是在那一步将Java类转换为BeanDefinition的,奥秘就在AbstractApplication中的refresh方法中。在"向容器中注入bean的几种方式"文章中也提到我们可以通过实现BeanDefinition相关的接口实现对bean的注入.
具体的代码就不贴了。我个人觉得没啥必要,八股文只要讲清思想就好,非要扣代码背流程没啥必要。再说那些类型晦涩难背,看一遍忘一遍还不如多看点别的。
实例化
实例化意思是只是底层是通过工厂+反射完成创建获得一个空对象,这也是解决循环依赖的一个很重要的点,在实例化前后分别由两个钩子方法。
- 主要执行了Bean实例化之前会执行InstantiationAwareBeanPostProcess.postProcessBeforeInstantiation()方法
- Bean实例化之后会执行InstantiationAwareBeanPostProcess.postProcessAfterInstantiation()方法
实例化后会向实例化出的空对象中注入依赖的对象,这里又是另外一个考点,spring bean如何解决循环依赖的,下一篇讲。
初始化
1.执行BeanPostProcessor接口的postProcessBeforeInitialization方法进行前置初始化。
2.检查是否实现了InitializingBean一些接口,如果实现了就调用afterPropertiesSet方法完成初始化,这样如果想在对象创建完之后调用其他bean的方法,可以通过afterPropertiesSet方法完成调用。
3.执行BeanPostProcessor后置处理接口ProcessAfterInitialization方法进行后置处理。比如一些扫描所有bean做一些建立后台任务的操作。
销毁
销毁主要看是否实现了DisposbleBean接口调用destroy方法,实现了的话会在销毁阶段调用,比如连接池关闭等操作都可以放在这里。
总结
- 首先大体分为四个阶段,beanDefine、实例化、依赖注入、初始化
- SpringBoot启动流程中会扫描对应的注解将对应的Java类配置成BeanDefinition并存到Map中
- 实例化前后主要会执行两个hook函数,postProcessBeforeInstantiation与postProcessAfterInstantiation函数。
- 初始化则判断是否实现BeanPostProcessor,检查检查是否实现了InitializingBean等接口调用对应的hook函数。
- 销毁调用DisposbleBean的destroy方法