在Spring 启动流程概述 中,分析了 Spring 的启动流程。本文就来说明一下 Spring Bean 整个生命周期。如果有不清楚的地方,可以参考上文的“附录:启动日志”。
直接上图:Spring Bean 生命周期流程图。内容较多,图片文字偏小,请放大看(矢量图,可以任意放大):
Figure 1. Spring Bean 生命周期流程图
下面是文字说明。
从 getBean() 方法获取 Bean 时,如果缓存中没有对应的 Bean,则会创建 Bean,整个流程如下:
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation — 目前有如下四个:
ImportAwareBeanPostProcessor AnnotationAwareAspectJAutoProxyCreator CommonAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor
构造函数
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition — 目前有如下三个:
CommonAnnotationBeanPostProcessor — 收集 @Resource 依赖信息, initMethods 和 destroyMethods 等信息。(就是 @PostConstruct 和 @PreDestroy 标注的方法。)
AutowiredAnnotationBeanPostProcessor — 收集 @Autowired 的依赖信息。
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 开始废弃,使用上面方法代替。
| Warning |
这里要注意,并不是执行完四个类的 postProcessProperties 方法,再去执行四个类的 postProcessPropertyValues 方法。而是以类为顺序的,执行完一个类的 postProcessProperties 方法,然后去执行 postProcessPropertyValues 方法。执行完一个类,再去执行下一个类。这个现象在下面的日志中有反应。 |
AutowiredAnnotationBeanPostProcessor#setBeanFactory(DefaultListableBeanFactory) — 通过 AbstractAutowireCapableBeanFactory#invokeAwareMethods 方法如下 Aware 注入:
BeanNameAware BeanClassLoaderAware BeanFactoryAware
BeanPostProcessor#postProcessBeforeInitialization — 目前有
用户手动添加的 BeanPostProcessor
ApplicationContextAwareProcessor — 完成如下六个 Aware 的注入:
EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware ApplicationContextAware
ImportAwareBeanPostProcessor — 如果实现了 ImportAware 接口,则注入 importMetadata 信息。
BeanPostProcessorChecker — 无所事事。
AnnotationAwareAspectJAutoProxyCreator — 无所事事。
CommonAnnotationBeanPostProcessor — 要调用 LifecycleMetadata#invokeInitMethods 方法,但是,里面去没有任何实现,似乎调用了全局设置的初始化操作。需要找文档确认一下。
AutowiredAnnotationBeanPostProcessor — 继承父类实现,无所事事。
ApplicationListenerDetector — 无所事事。
InitializingBean#afterPropertiesSet()
init-method
BeanPostProcessor#postProcessAfterInitialization 方法 — 目前有
用户手动添加的 BeanPostProcessor
ApplicationContextAwareProcessor — 继承默认实现,无所事事。
ImportAwareBeanPostProcessor — 继承默认实现,无所事事。
BeanPostProcessorChecker — 如果 Bean 是 BeanPostProcessor 子类,则检查 BeanPostProcessor 数量。
AnnotationAwareAspectJAutoProxyCreator — 检查 Bean 和提前暴露的引用是否相同,不同则重新生成代理对象。
CommonAnnotationBeanPostProcessor — 继承父类实现,无所事事。
AutowiredAnnotationBeanPostProcessor — 继承父类实现,无所事事。
ApplicationListenerDetector — 将 ApplicationListener 类型的 Bean,加入到容器的 applicationListeners 中,方便容器开始监听。
初始化之前,似乎可以设置全局的初始化操作。忘了具体在哪个类中了?
下面对创建 Bean 的流程做进一步说明:
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 通过 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法,调用 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法。遍历 InstantiationAwareBeanPostProcessor 列表( getBeanPostProcessorCache().instantiationAware 变量)时,如果返回值不为空,则立即返回,不再继续调用。不为空,则表示创建了 Bean 对象,然后马上调用 BeanPostProcessor#postProcessAfterInitialization 方法。如果这里创建对象,则直接返回该对象,不再进行下面的调用。有四个 InstantiationAwareBeanPostProcessor 对象:
ConfigurationClassPostProcessor AnnotationAwareAspectJAutoProxyCreator CommonAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 通过 AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors 调用 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法。变量: getBeanPostProcessorCache().mergedDefinition 。 这个方法主要干什么?通过 CommonAnnotationBeanPostProcessor#applyMergedBeanDefinitionPostProcessors 调用 CommonAnnotationBeanPostProcessor#findResourceMetadata 可以看出,这个地方可以获取依赖信息。带验证。 系统中有如下四个类:
CommonAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor ApplicationListenerDetector InitDestroyAnnotationBeanPostProcessor
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 列表。
ConfigurationClassPostProcessor AnnotationAwareAspectJAutoProxyCreator CommonAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor
InstantiationAwareBeanPostProcessor#postProcessProperties 接着调用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法来完成属性注入。
InstantiationAwareBeanPostProcessor#postProcessPropertyValues 然后再执行 InstantiationAwareBeanPostProcessor#postProcessPropertyValues 。这个方法马上从 5.1 开始要废弃掉,使用上述 postProcessProperties 代替。
到这里 populateBean 方法结束。
AutowiredAnnotationBeanPostProcessor#setBeanFactory(DefaultListableBeanFactory) BeanPostProcessor#postProcessBeforeInitialization 调用 BeanPostProcessor#postProcessBeforeInitialization 方法。
InitializingBean#afterPropertiesSet() init-method init 方法。
BeanPostProcessor#postProcessAfterInitialization 调用 BeanPostProcessor#postProcessAfterInitialization 方法。
调用 beanFactory.destroyBean(bean) 方法,开始销毁 Bean。
调用 DestructionAwareBeanPostProcessor#postProcessBeforeDestruction(Object bean, String beanName) — ApplicationListenerDetector 就是一个 DestructionAwareBeanPostProcessor 。但是,Bean 销毁时,不知道为什么没有被调用。
调用 DisposableBean#destroy() 方法
如果还有 destroy-method ,接着通过反射调用 destroy-method 方法。