生命周期的整体流程
Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。
而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。
了解 Spring 生命周期的意义就在于,可以利用 Bean 在其存活期间的指定时刻完成一些相关操作,即扩展点。这种时刻可能有很多,但一般情况下,会在 Bean 被初始化后和被销毁前执行一些相关操作。具体扩展点的使用可以看这篇文章,可以这两篇文章结合着看。
在执行初始化方法之前和之后,还需要对Bean的后置处理器BeanPostProcessors进行处理:
在invokeInitMethods 的前后进行applyBeanPostProcessorsBeforeInitialization,applyBeanPostProcessorsAfterInitialization
在后置处理中处理了包括:AOP【AnnotationAwareAspectJAutoProxyCreator】,负责 构造后@PostConstruct 和 销毁前@PreDestroy 的 InitDestoryAnnotationBeanPostProcessor 等
以及通过实现BeanPostProcessor接口的自定义处理器
- Bean生命周期整体流程如下:
加载Bean定义:通过 loadBeanDefinitions 扫描所有xml配置、注解将Bean记录在beanDefinitionMap中。即IOC容器的初始化过程
Bean实例化:遍历 beanDefinitionMap 创建bean,最终会使用getBean中的doGetBean方法调用 createBean来创建Bean对象
构建对象:容器通过 createBeanInstance 进行对象构造
1. 获取构造方法(大部分情况下只有一个构造方法)
1. 如果只有一个构造方法,无论这个构造方法有没有入参,都用这个构造方法
1. 有多个构造方法时
1. 先拿带有@Autowired的构造方法,但是如果多个构造方法都有@Autowired就会报错
1. 如果没有带有@Autowired的构造方法,那就找没有入参的;如果多个构造方法都是有入参的,那也会报错
1. 准备参数
1. 先根据类进行查找
1. 如果这个类有多个实例,则再根据参数名匹配
1. 如果没有找到则报错
1. 构造对象:无参构造方法则直接实例化
填充属性:通过populateBean方法为Bean内部所需的属性进行赋值,通常是 @Autowired 注解的变量;通过三级缓存机制进行填充,也就是依赖注入
初始化Bean对象:通过initializeBean对填充后的实例进行初始化
1. 执行Aware:检查是否有实现者三个Aware:`BeanNameAware`,`BeanClassLoaderAware`, `BeanFactoryAware`;让实例化后的对象能够感知自己在Spring容器里的存在的位置信息,创建信息
1. 初始化前:BeanPostProcessor,也就是拿出所有的后置处理器对bean进行处理,当有一个处理器返回null,将不再调用后面的处理器处理。
1. 初始化:afterPropertiesSet,init- method;
1. 实现了InitializingBean接口的类执行其afterPropertiesSet()方法
1. 从BeanDefinition中获取initMethod方法
1. 初始化后:BeanPostProcessor,;获取所有的bean的后置处理器去执行。AOP也是在这里做的
- 注册销毁:通过reigsterDisposableBean处理实现了DisposableBean接口的Bean的注册
1. Bean是否有注册为DisposableBean的资格:
1. 是否有destroyMethod。
1. 是否有执行销毁方法的后置处理器。
1. DisposableBeanAdapter: 推断destoryMethod
1. 完成注册
添加到单例池:通过 addSingleton 方法,将Bean 加入到单例池 singleObjects
销毁
销毁前:如果有@PreDestory 注解的方法就执行
如果有自定义的销毁后置处理器,通过 postProcessBeforeDestruction 方法调用destoryBean逐一销毁Bean
销毁时:如果实现了destroyMethod就执行 destory方法
执行客户自定义销毁:调用 invokeCustomDestoryMethod执行在Bean上自定义的destroyMethod方法
1. 有这个自定义销毁就会执行
1. 没有自定义destroyMethod方法就会去执行close方法
1. 没有close方法就会去执行shutdown方法
1. 都没有的话就都不执行,不影响
Bean的实例化
BeanFactory定义了Bean容器的规范,其中包含根据bean的名字, Class类型和参数等来得到bean实例。
IoC初始化时,最终是将Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap;并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等;
当需要进行创建Bean对象时,就是通过遍历beanDefinitionMap来创建Bean
主体思路
BeanFactory实现getBean方法在AbstractBeanFactory中,这个方法重载都是调用doGetBean方法进行实现的:
doGetBean
我们来看下doGetBean方法(这个方法很长,我们主要看它的整体思路和设计要点):
逻辑流程如下:
解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
无参单例先从缓存中尝试获取
如果bean实例还在创建中,则直接抛出异常
如果bean definition 存在于父的bean工厂中,委派给父Bean工厂获取
标记这个beanName的实例正在创建
确保它的依赖也被初始化
真正创建
单例时
原型时
根据bean的scope创建
接下来就是Bean真正创建的过程
createBean
这个方法整体流程图如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
①实例化之前
会对Bean的后置处理器BeanPostProcessors进行处理
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
②doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
①构建对象
createBeanInstance创建一个Bean实例,就是返回一个原始对象
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
②填充属性
Spring使用实现了InstantiationAwareBeanPostProcessor的后置处理器对实例化后的Bean进行处理
@Autowired注解的AutowiredAnnotationBeanPostProcessor
@Resource注解的CommonAnnotationBeanPostProcessor
byName和byType|
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
③初始化Bean对象
通过initializeBean对填充属性后的实例进行初始化
执行Aware:检查是否有实现着三个Aware,BeanNameAware,BeanClassLoaderAware, BeanFactoryAware
初始化前:BeanPostProcessor
初始化:afterPropertiesSet,init- method
初始化后:BeanPostProcessor, AOP
如果是单列Bean,则加入单例池当中。以后使用单例,从单例池中获取
执行Aware
就是看看有没有实现这三个Aware,有的话就执行相关方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
初始化前
拿出所有的后置处理器对bean进行处理,当有一个处理器返回null,将不再调用后面的处理器处理。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
完成初始化前的操作有2种方式:
TestBeanPostProcessor 实现了 BeanPostProcessor,重写postProcessBeforeInitialization方法。
使用@PostConstruct。由CommonAnnotationBeanPostProcessor处理器处理。@PostConstruct是在实例化bean完成之后
初始化时
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
实现了InitializingBean接口的类执行其afterPropertiesSet()方法
从BeanDefinition中获取initMethod方法。
可以是xml文件中配置的:
或者是@Bean注解配置:
初始化后
getBeanPostProcessors()获取所有的后置处理器,包括自己定义的
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
特别注意:.在实例化前如果获取到了bean那么将不执行spring正常创建bean的流程,而是直接调用初始化后的方法完成初始化后的操作。

④注册销毁
Spring在容器关闭时,会remove容器里所有的Bean。如果需要某些Bean在被Spring删除前执行一些逻辑,Spring也可以做到,那么就需要在Bean完成创建时将这个Bean注册为DisposableBean。
Bean是否有注册为DisposableBean的资格,是否有destroyMethod。
是否有执行销毁方法的后置处理器。
DisposableBeanAdapter
推断destoryMethod
指定的destroyMethod, AutoCloseable(close方 法),没有shutdown方法
完成注册:就是将完成包装的DisposableBeanAdapter, put到 销毁容器中。
是否有注册为DisposableBean的资格
判断某个bean是否拥有destroyMethod方法
是否有执行销毁方法的后置处理器
由DestructionAwareBeanPostProcessor去标识一个Bean是否需要销毁,并且交给这个后置处理器去处理销毁前的逻辑。
DisposableBeanAdapter
当一个bean有资格成为DisposableBean的时候,Spring不是将这个Bean直接放到需要销毁的容器当中,而是将其包装为DisposableBeanAdapter对象放入销毁容器中。
单例Bean销毁容器是一个以beanName为key,DisposableBean为value的Map。
推断destoryMethod
在将Bean包装为DisposableBeanAdapter时,要去推断destoryMethod。
推断方法名:
如果指定了DestroyMethod 就返回指定的。
有推断标记或者实现了AutoCloseable接口,再看是否实现DisposableBean接口的;如果实现了就直接返回null,如果没有实现就去推断是否有公有close方法,有就返回,没有再去推断是否有公有的shutdown方法,有就返回。
推断方法:
根据方法名推断方法,获取最少参数的方法对象method。如果method的参数大于1会报错,如果等于1且参数类型不为boolean类型也会报错。
完成注册
就是将完成包装的DisposableBeanAdapter, put到 销毁容器中。
添加到单例池
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory)
销毁
这里只关心单例Bean的销毁。Spring容器关闭时,会去销毁单例Bean。如果不去手动关闭容器,那么以上destroyMethod都不能执行。
总结销毁逻辑:
销毁前:如果有@PreDestory 注解的方法就执行
如果有自定义的销毁后置处理器,通过 postProcessBeforeDestruction 方法调用destoryBean逐一销毁Bean
销毁时:如果实现了destroyMethod就执行 destory方法
执行客户自定义销毁:调用 invokeCustomDestoryMethod执行在Bean上自定义的destroyMethod方法
手动执行close方法
org.springframework.context.support.AbstractApplicationContext#close
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingletons