Spring Bean 生命周期概述
在 Spring 启动流程概述 中,分析了 Spring 的启动流程。本文就来说明一下 Spring Bean 整个生命周期。如果有不清楚的地方,可以参考上文的“附录:启动日志”。
直接上图:Spring Bean 生命周期流程图。内容较多,图片文字偏小,请放大看(矢量图,可以任意放大):
下面是文字说明。
Bean 生命周期简述
调用
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation,主要是判断AnnotationAwareAspectJAutoProxyCreator是否可以生成代理。调用构造函数
调用
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition,主要是通过CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor收集依赖信息。InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,这步什么也没做。调用
InstantiationAwareBeanPostProcessor#postProcessProperties,主要是完成依赖注入。调用
AutowiredAnnotationBeanPostProcessor#setBeanFactory,注入BeanFactory等相关信息。调用
BeanPostProcessor#postProcessBeforeInitialization,主要是注入ApplicationContext等相关信息。调用
InitializingBean#afterPropertiesSet、init-method方法调用
BeanPostProcessor#postProcessAfterInitialization,主要是生成 AOP 代理类。
Bean 生命周期详解
从 getBean() 方法获取 Bean 时,如果缓存中没有对应的 Bean,则会创建 Bean,整个流程如下:
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation— 目前有如下四个:ImportAwareBeanPostProcessor— 继承父类实现,无所事事。AnnotationAwareAspectJAutoProxyCreator— 继承父类实现,判断是否属于基础切面类,如果有指定的 Target 则生成代理。CommonAnnotationBeanPostProcessor— 无所事事。AutowiredAnnotationBeanPostProcessor— 继承父类实现,无所事事。
构造函数
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition— 目前有如下三个:CommonAnnotationBeanPostProcessor— 收集@Resource依赖信息,initMethods和destroyMethods等信息。(就是@PostConstruct和@PreDestroy标注的方法。)这些信息被缓存到了this.injectionMetadataCache变量中,注入时从这个变量中取值。AutowiredAnnotationBeanPostProcessor— 收集@Autowired的依赖信息。这些信息被缓存到了this.injectionMetadataCache变量中,注入时从这个变量中取值。ApplicationListenerDetector— 判断 Bean 是否是一个ApplicationListener,是则保留,在后面的postProcessAfterInitialization方法中,加入到容器的applicationListeners中。
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation— 与上面的postProcessBeforeInstantiation方法对应,目前有如下四个:ImportAwareBeanPostProcessor— 继承父类实现,无所事事。AnnotationAwareAspectJAutoProxyCreator— 继承父类实现,无所事事。CommonAnnotationBeanPostProcessor— 无所事事。AutowiredAnnotationBeanPostProcessor— 无所事事。
InstantiationAwareBeanPostProcessor#postProcessProperties— 目前有如下三个:ImportAwareBeanPostProcessor— 如果 Bean 是EnhancedConfiguration(它继承了BeanFactoryAware) 的实现类,则注入BeanFactory。AnnotationAwareAspectJAutoProxyCreator— 无所事事。CommonAnnotationBeanPostProcessor— 完成@Resource依赖注入。在这里会递归创建所依赖 Bean。调试代码,弄清楚。
AutowiredAnnotationBeanPostProcessor— 完成@Autowired和@Value注入
InstantiationAwareBeanPostProcessor#postProcessPropertyValues— 从 5.1 开始废弃,使用上面方法代替。这里要注意,并不是执行完四个类的 postProcessProperties方法,再去执行四个类的postProcessPropertyValues方法。而是以类为顺序的,执行完一个类的postProcessProperties方法,然后去执行postProcessPropertyValues方法。执行完一个类,再去执行下一个类。这个现象在下面的日志中有反应。AutowiredAnnotationBeanPostProcessor#setBeanFactory(DefaultListableBeanFactory)— 通过AbstractAutowireCapableBeanFactory#invokeAwareMethods方法如下Aware注入:BeanNameAwareBeanClassLoaderAwareBeanFactoryAware
BeanPostProcessor#postProcessBeforeInitialization— 目前有用户手动添加的
BeanPostProcessorApplicationContextAwareProcessor— 完成如下六个Aware的注入:EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAwareApplicationContextAware
ImportAwareBeanPostProcessor— 如果实现了ImportAware接口,则注入importMetadata信息。BeanPostProcessorChecker— 无所事事。AnnotationAwareAspectJAutoProxyCreator— 无所事事。CommonAnnotationBeanPostProcessor— 要调用LifecycleMetadata#invokeInitMethods方法,但是,里面去没有任何实现,似乎调用了全局设置的初始化操作。需要找文档确认一下。AutowiredAnnotationBeanPostProcessor— 继承父类实现,无所事事。ApplicationListenerDetector— 无所事事。
InitializingBean#afterPropertiesSet()init-methodBeanPostProcessor#postProcessAfterInitialization方法 — 目前有用户手动添加的
BeanPostProcessorApplicationContextAwareProcessor— 继承默认实现,无所事事。ImportAwareBeanPostProcessor— 继承默认实现,无所事事。BeanPostProcessorChecker— 如果 Bean 是BeanPostProcessor子类,则检查BeanPostProcessor数量。AnnotationAwareAspectJAutoProxyCreator— 检查 Bean 和提前暴露的引用是否相同,不同则重新生成代理对象。注意:绝大部分的 AOP 代理生成都是在这个方法中完成的。在 Spring AOP 源码分析:入门 中有更详细的说明。CommonAnnotationBeanPostProcessor— 继承父类实现,无所事事。AutowiredAnnotationBeanPostProcessor— 继承父类实现,无所事事。ApplicationListenerDetector— 将ApplicationListener类型的 Bean,加入到容器的applicationListeners中,方便容器开始监听。
初始化之前,似乎可以设置全局的初始化操作。忘了具体在哪个类中了?
Bean 生命周期补充说明
下面对创建 Bean 的流程做进一步说明:
.1. InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
通过 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法,调用 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法。遍历 InstantiationAwareBeanPostProcessor 列表(getBeanPostProcessorCache().instantiationAware 变量)时,如果返回值不为空,则立即返回,不再继续调用。不为空,则表示创建了 Bean 对象,然后马上调用 BeanPostProcessor#postProcessAfterInitialization 方法。如果这里创建对象,则直接返回该对象,不再进行下面的调用。有四个 InstantiationAwareBeanPostProcessor 对象:
ConfigurationClassPostProcessorAnnotationAwareAspectJAutoProxyCreatorCommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessor
.2. Bean 的构造函数
.3. MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
通过 AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors 调用 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法。变量: getBeanPostProcessorCache().mergedDefinition。这个方法主要干什么?通过 CommonAnnotationBeanPostProcessor#applyMergedBeanDefinitionPostProcessors 调用 CommonAnnotationBeanPostProcessor#findResourceMetadata 可以看出,这个地方可以获取依赖信息。带验证。系统中有如下四个类:
CommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessorApplicationListenerDetectorInitDestroyAnnotationBeanPostProcessor— 这个有吗?没有加入到变量中。
.4. InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
有一点重要的信息,日志中没有体现出来。设置 Bean 的属性是在执行 BeanPostProcessor 调用之前完成的。在 AbstractAutowireCapableBeanFactory#doCreateBean 方法中,调用了 AbstractAutowireCapableBeanFactory#populateBean 方法来设置属性,然后去调用的 BeanPostProcessor 和 init 方法。populateBean 方法是通过调用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法来完成注入,其中 CommonAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor 分别处理不同的注解。下面是 populateBean 方法更详细的说明。
在注入 Bean 属性之前,调用 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation。(从变量 getBeanPostProcessorCache().instantiationAware 中获取列表。)容器完成初始化后,有 ImportAwareBeanPostProcessor,AnnotationAwareAspectJAutoProxyCreator, CommonAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor 四个 InstantiationAwareBeanPostProcessor 对象。但是,这四个类,没有做任何操作。如果返回值为 false 则中断,不再继续遍历 InstantiationAwareBeanPostProcessor 列表。
ConfigurationClassPostProcessorAnnotationAwareAspectJAutoProxyCreatorCommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessor
.5. InstantiationAwareBeanPostProcessor#postProcessProperties
接着调用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法来完成属性注入。
.6. InstantiationAwareBeanPostProcessor#postProcessPropertyValues
然后再执行 InstantiationAwareBeanPostProcessor#postProcessPropertyValues。这个方法马上从 5.1 开始要废弃掉,使用上述 postProcessProperties 代替。
到这里 populateBean 方法结束。
.7. AutowiredAnnotationBeanPostProcessor#setBeanFactory(DefaultListableBeanFactory)
.8. BeanPostProcessor#postProcessBeforeInitialization
调用 BeanPostProcessor#postProcessBeforeInitialization 方法。
.9. InitializingBean#afterPropertiesSet()
.10. init-method
init 方法。
.11. BeanPostProcessor#postProcessAfterInitialization
调用 BeanPostProcessor#postProcessAfterInitialization 方法。
Bean 销毁流程
调用
beanFactory.destroyBean(bean)方法,开始销毁 Bean。调用
DestructionAwareBeanPostProcessor#postProcessBeforeDestruction(Object bean, String beanName)—ApplicationListenerDetector就是一个DestructionAwareBeanPostProcessor。但是,Bean 销毁时,不知道为什么没有被调用。调用
DisposableBean#destroy()方法如果还有
destroy-method,接着通过反射调用destroy-method方法。



