1. 简介
在【Spring核心流程梳理】我们介绍了Spring容器的refresh过程,但是我们并没有进入到Spring Bean的创建等生命周期等内容。
这里,就来梳理一下Spring Bean的生命周期。
我们还是关注流程,重点关注核心的入口,忽略具体实现的细节。
目标也很简单:
- 知道Spring Bean相关的扩展点,方便我们做自定义和阅读源码
- 当遇到问题的时候,能大致了解相关的debug入口
2. Bean处理器
2.1 BeanPostProcessor
在开始之前,先简单聊两句BeanPostProcessor,因为Bean的很多处理过程涉及到它,有点俄罗斯套娃的感觉。
1Object postProcessBeforeInitialization(Object bean, String beanName) 2Object postProcessAfterInitialization(Object bean, String beanName)
首先要弄清楚什么是Initialization,初始化,才知道是那之前那之后,我们可以做点啥。
初始化,就是我们调用类的实例bean已经创建好了,属性也设置好了。
调用我们自定义的:InitializingBean的afterPropertiesSet,init-method方法的过程。
所以,postProcessBeforeInitialization是在bean的属性设置之后被调用。
然后,afterPropertiesSet,init-method被调用。
最后,postProcessAfterInitialization被调用
2.2 InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor继承了BeanPostProcessor,多添加了下面3个方法:
1@Nullable 2default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { 3 return null; 4} 5default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { 6 return true; 7} 8@Nullable 9default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) 10 throws BeansException { 11 return null; 12}
实例化Instantiation是什么过程呢,简单的来说就是new过程,Spring当然是通过反射完成。
postProcessBeforeInstantiation就是在一个bean new之前被调用。 postProcessAfterInstantiation是在bean new之后被调用。
postProcessProperties这个方法是在这个bean的property和value解析完成之后被调用。
2.3 SmartInstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor继承了InstantiationAwareBeanPostProcessor,又添加了3个方法:
1// 探测bean的类型 2Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException; 3 4// 选择合适的构造器 5Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException; 6 7// 获得早期暴露的bean引用,Spring处理循环引用就用到这个方法 8Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;
你也可以看看BeanPostProcessor与Spring无侵入扩展这篇文章。
3. AbstractAutowireCapableBeanFactory
如果Spring容器的核心是AbstractApplicationContext,那么Spring Bean相关的流程的核心就是AbstractAutowireCapableBeanFactory。
Bean生命周期最重要的流程就3个:
- 实例化(Instantiate):创建实例,相当于new过程
- 初始化(Initialize):设置值的过程,相当于setter过程
- 销毁:一般不需要,特殊的可以做释放资源等工作
注意:Instantiate和Initialize两个单词咋看很像,但是两个流程还是有很大差别,不要高混淆了
我们从AbstractApplicationContext的refresh方法中可以知道Bean创建的相关流程入口是:finishBeanFactoryInitialization方法。
调用链很长,分支很多,我们直接聚焦到核心的方法:AbstractAutowireCapableBeanFactory的doCreateBean方法。
3.1 doCreateBean方法
1protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 2 throws BeanCreationException { 3 4 // 实例化流程,创建bean实例 5 BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args); 6 7 // 初始化bean实例 8 Object exposedObject = bean; 9 //设置property value,相当于setter过程 10 populateBean(beanName, mbd, instanceWrapper); 11 exposedObject = initializeBean(beanName, exposedObject, mbd); 12 13 // 销毁相关流程 14 registerDisposableBeanIfNecessary(beanName, bean, mbd); 15 return exposedObject; 16 }
上面的方法是伪代码,从原来代码中抽取出核心流程的部分,避免被无关的信息所干扰。
创建bean(new)的流程入口createBeanInstance这里我们暂时不关注,我本只需要知道,现在通过反射我们获取到一个Bean的实例了。
接下来我们来看初始化的流程,首先populateBean,populate是添加输入数据的意思,根据名字我们也能猜出大概是要执行setter方法了。
3.2 populateBean方法
1protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { 2 // InstantiationAwareBeanPostProcessor是BeanPostProcessor的子类,这里是调用其bean实例化之后的注入接口 3 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 4 for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { 5 if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { 6 return; 7 } 8 } 9 } 10 11 // 后面是,获取的bean的PropertyValues,解析是否需要自动注入,检查PropertyValues有没有需要预处理等流程 12 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); 13 14 // 15 if (pvs != null) { 16 applyPropertyValues(beanName, mbd, bw, pvs); 17 } 18}
3.3 initializeBean方法
1protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { 2 // 检查bean是否是BeanNameAware、BeanClassLoaderAware、BeanFactoryAware调用对应方法 3 invokeAwareMethods(beanName, bean); 4 5 // 调用BeanPostProcessor的postProcessBeforeInitialization来处理bean 6 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); 7 8 // 如果bean实现了InitializingBean,调用其afterPropertiesSet,如果有init-method,也会在afterPropertiesSet之后调用 9 invokeInitMethods(beanName, wrappedBean, mbd); 10 11 // 调用BeanPostProcessor的postProcessAfterInitialization来处理bean 12 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 13 return wrappedBean; 14}
@PostConstuct并没有在initializeBean处理,而是通过CommonAnnotationBeanPostProcessor、InitDestroyAnnotationBeanPostProcessor实现。
这2个类一看就能猜到是BeanPostProcessor,事实上的确是在InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization方法中处理。
因为initializeBean是初始化方法,@PostConstuct是在初始化之前执行,所以,调用顺序就能确定了:
- @PostConstuct方法
- afterPropertiesSet
- init-method
initializeBean方法中处理的Aware是:
- BeanNameAware给bean设置beanName
- BeanClassLoaderAware给bean设置ClassLoader
- BeanFactoryAware给bean设置BeanFactory
其他的Aware,通过ApplicationContextAwareProcessor,它是一个BeanPostProcessor,会在bean初始化之前,但是肯定在前面3个之后调用:
- EnvironmentAware:设置获取环境属性相关的Enviroment
- EmbeddedValueResolverAware:设置SpEL解析器
- ResourceLoaderAware:设置资源加载器
- ApplicationEventPublisherAware:设置事件发布器
- MessageSourceAware:设置国际化相关的MessageSource
- ApplicationStartupAware:设置启动指标监控相关的ApplicationStartup
- ApplicationContextAware:设置容器本身ApplicationContext
3.4 registerDisposableBeanIfNecessary方法
这个方法咱就不细入了,简单说一下逻辑:
- 处理bean中有@PreDestroy注解的方法
- 如果实现了DisposableBean接口处理其destroy方法
- 检查destroy-method,如:<bean id="x" class="XX" destroy-method="destroyMethod"/>
4. Spring Bean生命周期小结
先看一个简化流程: 
在看一下常规流程逻辑调用链:

5. 循环依赖
Spring Bean的创建过程中还有一个重要的问题,依赖循环,这里大致说2句。
1public class A { 2 @Resource 3 private B b; 4} 5 6public class B { 7 @Resource 8 private A a; 9}
这可咋整哦?
逻辑可以通过的DefaultSingletonBeanRegistry的三级缓存来处理:
1// 缓存已经创建完成的bean 2private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 3 4// 缓存ObjectFactory 5private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); 6 7// 缓存还未进行依赖注入和初始化方法调用的bean实例 8private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); 9 10 11protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException { 12 // 如果是单例,并且允许循环引用,并且这个实例正在创建中 13 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); 14 if (earlySingletonExposure) { 15 //把这个实例包装成ObjectFactory添加到三级缓存中,这样有其他引用就可以暂时获取这个未创建完成的bean 16 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 17 } 18 19 // 设置属性等初始化过程 20 21 return exposedObject; 22 }
用个简单的流程图来大致说明一下: 
1public class A { 2 public A(B b) { 3 } 4} 5 6public class B { 7 public B(A a) { 8 } 9}
Spring的Bean创建流程我们也知道,构造函数上的循环依赖是没有办法处理的,实例化都执行不了。