从BeanFactory源码看Bean的生命周期

下图是我搜索“Spring Bean生命周期”找到的图片,来自文章——Spring Bean的生命周期

从BeanFactory源码看Bean的生命周期

文章插图
下面,我们从AbstractAutowireCapableBeanFactory的源码中来分析这张图的各个阶段到底是怎么执行的 。BeanFactory的基本源码解读在Spring BeanFactory接口分析&源码解读这篇文章中,如果读本篇文章稍显吃力,可以先去看看上面那篇 。
我们所用到的BeanFactory,ApplicationContext基本都继承了AbstractAutowireCapableBeanFactory,它是一个具有自动装载能力的BeanFactory,它可以响应@Autowire注解,所以,单独分析这个类不是没用的,而且很有必要 。
同时,由于Spring的BeanFactory层次结构中大量的使用了模板模式,所以我们可能在这个类的父子类中跳入跳出 。
Bean生命周期简单描述#我们先不看那些繁杂的生命周期方法回调,只看核心的部分,也就是图中四个大的黄色块
  1. 根据BeanDefinition创建Bean,这个过程称为实例化
  2. 填充Bean的属性
  3. 这时,Bean已经创建完毕并可以投入使用,这时需要调用Bean的初始化方法(如果用户指定了的话),这个过程称为初始化
  4. Bean被销毁
所以,可以将Bean的创建归纳为:
  1. 实例化
  2. 设置属性
  3. 初始化
  4. 销毁
虽然上面我们把大部分的繁杂的生命周期Hook给屏蔽了,总结出了四个核心的过程,但是这些Hook给了Spring框架带来了无尽的灵活性,所以也是非常重要的 。但它们太容易让人眼花了,所以在继续之前,我们有必要先介绍一下那些东西都是什么,是用来解决什么问题的 。
BeanPostProcessor接口#BeanPostProcessor接口有如下方法:
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean; }}从方法名上看,xxxxBeforeInitializationxxxAfterInitialization,意思是在初始化阶段前后做一些事,它的参数中,有实际创建出来的Bean和Bean的名字,该方法默认情况下返回原始的bean,也可以返回该bean的某种代理,实际上AOP就是通过这个接口来实现bean代理的返回的 。
所以,BeanPostProcessor实际关心的是Bean的初始化阶段 。
ConfigurableBeanFactory接口的addBeanPostProcessor方法可以向BeanFactory中注册BeanPostProcessor
InstantiationAwareBeanPostProcessor#首先,它继承BeanPostProcessor,所以它是一个BeanPostProcessor 。但是从名字来看,InstantiationAware表示它更关心对于Bean的实例化阶段的感知,而不是初始化阶段,它发生在初始化阶段前面 。
它的方法如下:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null; } default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true; } @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)throws BeansException {return null; }// 省略一个过时方法...}首先,xxxBeforeInstantiationxxxAfterInstantiation是很容易和之前的两个搞混的,不过以Instantiation结尾代表着它们关心的是Bean实例化的前后,在实例化前,该方法同样允许返回一个代替该Bean的对象,不过这次由于Bean还没有实际创建出来,所以它的参数中没有Bean对象,而是该Bean的Class对象 。而在实例化后,它允许返回一个布尔值来指定是否该对该Bean的属性进行设置(true设置,false跳过) 。

经验总结扩展阅读