Spring源码之Bean创建流程
主干方法
Bean创建生命周期流程图
流程分解
Bean的创建过程总的来说分为三个阶段
- 实例化,也就是创建bean实例,createBeanInstance
- Bean属性填充,也就是populateBean
- 初始化Bean,也就是initializingBean
这三个步骤中间又穿插了很多Spring容器提供的各种回调接口。其中最主要的回调接口有一下几类:
- BeanPostProcessor
- Aware类接口
- InitializingBean
- 用户自定义的initMethod
这几类回调接口的作用后续再介绍,我们先把关注点聚焦到Bean的创建过程上。
实例化
Spring根据不同的实例化策略来创建Bean实例。Spring中提供了一个InstantiationStrategy接口方面实现不同的实例化策略。Spring中有两种初始化策略:SimpleInstantiationStrategy和CglibSubclassingInstantiationStrategy。其中SimpleInstantiationStrategy支持构造器、工厂方法、FactoryBean等不同的实例化策略。另一个挖坑,专门介绍。
属性填充
实例化后的Bean,需要对Bean中的属性设置值。如:加了Autowired、Value、Resource等注解的字段,Spring需要做自动注入。如果Bean中的属性没有上述注解,但是指定了自动装配模式,也会按照指定模式进行属性自动装配。
属性填充分为5个小步骤:
- 执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation回调
- 进行ByName或ByType自动装配
- 执行InstantiationAwareBeanPostProcessor.postProcessProperties和postProcessPropertyValues回调
- 按照依赖检查模式进行依赖检查
- 真正将将2和3步骤中得到的属性值(PropertyValues)填充到Bean属性上
💡 Tips:
Spring在属性填充过程中会对Bean属性进行解析,并将需要填充的属性封装成为PropertyValues对象,在上述2,3,4步骤中不管是进行自动装配,还是InstantiationAwareBeanPostProcessor回调(其实Autowired自动装配就是在这一步完成的),甚至是依赖检查,操作对象都是PropertyValues.只有最后一步5,才真正将属性值设置到Bean属性上
初始化
初始化就是对Bean中属性的进一步加工处理。比如:调用各类Aware接口,调用InitializingBean的afterPropertiesSet方法等。它又分为4个小步骤:
- 调用各种Aware接口的回调方法
- 调用 BeanPostProcessor的postProcessBeforeInitialization方法
- 调用初始化方法 主要包括:InitializingBean的afterPropertiesSet和用户自定义的初始化方法
- 调用 BeanPostProcessor的postProcessAfterInitialization方法
至此,整个bean创建完成。
回调接口
上文中的四类回调接口,还可以再分类。
其中BeanPostProcessor单独一类,它是容器级别的回调接口,它对所有的Bean都有效。也就是说,在容器中每个Bean创建的过程中,BeanPostProcessor中的回调方法都执行一次。
其余的Aware类接口,InitializingBean和自定义的initMethod则是Bean级别的,它只对实现了该类接口的Bean有效。在Bean的创建过程中,只有创建实现了这些接口的Bean时,才会被调用。
BeanPostProcessor
挖坑
Aware类接口
XXXAware字面意思就是感知XXX,也就是为Bean提供感知XXX的能力。如BeanNameAware,让Bean感知到自己在容器中的beanName,ApplicationContextAware让bean感知到ApplicationContext以方便在Bean中调用ApplicationContext的方法。还有一类方法名字叫XXXCapable,字面意思就是XXX能力,也就是指这类Bean能够为容器提供XXX。如实现了EnvironmentCapable的Bean有能力向容器提供Environment.
InitializingBean和InitMethod
初始化阶段主要是执行初始化回调方法。这些自定义的初始化回调方法的主要作用就是将复杂Bean的初始化步骤封装到初始化方法中,而不用把所有的步骤都放在构造方法中。
Bean的销毁流程
- 如果Bean实现了DestructionAwareBeanPostProcessor接口,则调用该接口的postProcessBeforeDestruction()方法
- 如果Bean实现了DisposableBean接口,则调用该接口的destroy()方法
- 如果Bean存在自定义的destroy()方法,则调用该destory方法