SpringFramework 5.1.19.RELEASE
在《IOC & DI》中以 FileSystemXmlApplicationContext 为例从源码角度见到剖析了 一个类(class) 解析加载到 IOC 容器中的全过程。
下面以IOC的管理流程剖析 类(class) 在 SpringFreamework 中的生命周期。
IOC(Inversion of Control)
完整的整个流程总的分为三个步骤
- 步骤一:资源定位。即:定位需要被加载的 class 。
- 步骤二:载入。即:将定位的 class 解析为 Spring 待处理的结构定义:
BeanDefinition
对象。 - 步骤三:注册。即:(针对预实例化对象)将抽象为
BeanDefinition
对象的 class信息实例化为 Spring Bean。
一、Spring Bean 生命周期
根据代码执行顺序 Spring Bean 的生命周期概括为六个阶段
- 实例化(Instantiation)
- 属性赋值(Populate)
- 初始化(Initialization)
- 销毁前置处理类注册(Register DisposableBean)
- 使用中(In Use)
- 销毁(Destruction)
以《IOC&DI#懒加载实例》为例,查看Bean生命周期对应的源码 AbstractAutowireCapableBeanFactory#doCreateBean
,代码如下:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// Instantiate the bean.
// 1、实例化对象
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 构造函数注入,如:@Autowired 标注的构造函数
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 省略
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 2、设置属性(填充bean)
populateBean(beanName, mbd, instanceWrapper);
// 3、初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// 省略
// Register bean as disposable.
try {
// 4、设置销毁回调相关bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
// 省略
return exposedObject;
}
}
如上述代码所示,分别对应 Spring Bean 生命周期的四个阶段:实例化(Instantiation)
、属性赋值(Populate)
、初始化(Initialization)
、销毁前置处理类注册(Register DisposableBean)
。
针对 Bean 的使用
无处不在,比如使用 @Autowired
注入等方式使用。
针对 Bean的销毁(Destruction)
在销毁 Spring IOC 过程中进行,相关代码在 AbstractApplicationContext#doClose
中。
1.1、实例化(Instantiation)
1.2、属性赋值(Populate)
属性赋值,即对标注了 [@Autowired](https://docs.spring.io/spring-framework/docs/5.1.19.RELEASE/spring-framework-reference/core.html#beans-autowired-annotation)
、[@Resource](https://docs.spring.io/spring-framework/docs/5.1.19.RELEASE/spring-framework-reference/core.html#beans-resource-annotation)
、[@Value](https://docs.spring.io/spring-framework/docs/5.1.19.RELEASE/spring-framework-reference/core.html#beans-autowired-annotation)
的属性进行注入,以及 自定义初始化”@PostConstruct” 、销毁前置方法”@PreDestroy” 的设置。
代码入口为 AbstractAutowireCapableBeanFactory#populateBean
,部分代码如下:
根据如上图代码,简单分析属性设置中关于 @Autowired
、@Value
、@Inject
、@Resource
属性注入。
通过代码,以及官方文档,@Autowired
、@Value
、@Inject
、@Resource
属性注入由两个类负责
AutowiredAnnotationBeanPostProcessor
处理@Autowired
、@Value
、@Inject
属性注入CommonAnnotationBeanPostProcessor
处理@Resource
属性注入1.2.1、AutowiredAnnotationBeanPostProcessor 处理
@Autowired
、@Inject
都支持三种方式的注入:构造函数注入、方法注入、属性注入AutowiredAnnotationBeanPostProcessor# postProcessProperties
是方法注入和属性注入处理逻辑入口在属性赋值流程中调用。AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
用于获取构造注入操作数据,具体函数注入操作,介于 实例化和属性赋值之间的createBeanInstance
方法处理.
AutowiredAnnotationBeanPostProcessor
处理 @Autowired
、@Value
、@Inject
属性注入。
1.2.1.1、支持的注解
AutowiredAnnotationBeanPostProcessor
在实例化时即声明了类处理的注解,并缓存到集合中。
相关代码如下:
如代码所示,AutowiredAnnotationBeanPostProcessor
支持 @Autowired
、@Value
、@Inject
注解注入处理。
1.2.1.2、属性/方法 注入
在属性赋值流程中,会调用BeanPostProcessor#postProcessProperties
方法,对应 AutowiredAnnotationBeanPostProcessor#postProcessProperties
方法,关键代码如下:
属性注入的关键流程有两步
- step1、找到需要注入的属性,并构建元数据对象
InjectionMetadata
并对其进行缓存。
注入方式处理包含:属性注入和方法注入。
不同的方式构建不同的元数据结果- AutowiredMethodElement (方法注入元数据信息)
基于源码能够知道:AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
- 方法不能标注 static
- 方法参数不能为空
- AutowiredFieldElement(属性注入元数据信息)
基于源码知道:AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
- 属性不能标注 static
- AutowiredMethodElement (方法注入元数据信息)
- step2、进行属性的注入
根据方法注入或者属性注入通过反射的方式进行属性设置。
1.2.2、CommonAnnotationBeanPostProcessor 处理
CommonAnnotationBeanPostProcessor
处理 @Resource
1.2.2.1、支持的注解
CommonAnnotationBeanPostProcessor
支持 除 @Resource
属性注入外的,支持由 @PostConstruct
和 @PreDestory
标注的方法处理。
关于 @PostConstruct
和 @PreDestroy
在构造函数时即进行了声明。
而针对 @Resource
的处理,写死在具体处理逻辑CommonAnnotationBeanPostProcessor#buildResourceMetadata
中,代码如下:
1.2.2.2、属性/方法 注入
@Resource
注解仅支持方法和属性注入,不支持构造函数注入。
属性注入的关键流程有两步
- step1、找到需要注入的属性,并构建元数据对象
InjectionMetadata
并对其进行缓存。
注入方式处理包含:属性注入和方法注入。
不同的方式构建相同的元数据ResourceElement
ResourceElement
(isField = false 表示属性注入元数据信息)
基于源码能够知道:CommonAnnotationBeanPostProcessor#buildResourceMetadata
- 方法不能标注 static
- 方法参数不能为空且仅支持1个参数
ResourceElement
(isField = true 表示方法注入元数据信息)
基于源码知道:CommonAnnotationBeanPostProcessor#buildResourceMetadata
- 属性不能标注 static
- 属性不能是 javax.xml.ws.WebServiceContext
- step2、进行属性的注入
根据方法注入或者属性注入通过反射的方式进行属性设置。1.3、初始化(Initialization)
在四个阶段中,初始化(Initialization)
最复杂,包含了4个处理模块,同时这四个模块的处理也给程序开发提供了扩展点。
根据上述 Spring Bean 生命周期
图示 ,Bean 的初始化包含五大块操作逻辑
- XXXAware 接口处理
- BeanPostProcessor 前置处理
- InitializingBean 处理
- 自定义初始化方法处理
- BeanPostProcessor 后置处理
通过源码了解到初始化的入口 AbstractAutowireCapableBeanFactory#initializeBean
。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 省略
// Aware 接口调用处理,包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 前置处理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// InitializingBean 接口类处理,以及自定义初始化方法处理
invokeInitMethods(beanName, wrappedBean, mbd);
}
// 省略
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
}
1.3.1、XXXAware 接口处理
相关源码 AbstractAutowireCapableBeanFactory#invokeAwareMethods
如下:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
private void invokeAwareMethods(String beanName, Object bean) {
// Bean 必须实现了 Aware 接口
if (bean instanceof Aware) {
// Bean 如果实现了 BeanNameAware 接口处理
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// Bean 如果实现了 BeanClassLoaderAware 接口处理
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// Bean 如果实现了 BeanFactoryAware 接口处理
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
}
如代码所示,当 Bean 实现了 Aware
接口会进入三个判断处理逻辑
- 1、如果 Bean 实现了
BeanNameAware
接口
调用BeanNameAware#setBeanName
方法 - 2、如果 Bean 实现了
BeanClassLoaderAware
接口
调用BeanClassLoaderAware#setBeanClassLoader
方法 - 3、如果 Bean 实现了
BeanFactoryAware
接口
调用BeanFactoryAware#setBeanFactory
方法
1.3.2、BeanPostProcessor 前置处理
相关源码 AbstractAutowireCapableBeanFactory#AbstractAutowireCapableBeanFactory
如下:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
如代码所示,遍历所有的 BeanPostProcessor
并调用 BeanPostProcessor#postProcessBeforeInitialization
1.3.3、InitializingBean 接口及自定义初始化方法处理
相关源码 AbstractAutowireCapableBeanFactory#invokeInitMethods
如下:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
// 省略
// 如果实现了 InitializingBean 接口,相关处理
((InitializingBean) bean).afterPropertiesSet();
}
// 自定义初始化方法处理
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
}
如代码所示,分为两个处理逻辑
- 1、如果 Bean 实现了
InitializingBean
接口
调用InitializingBean#afterPropertiesSet
方法 -
1.3.4、BeanPostProcessor 后置处理
相关源码
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
如下public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
BeanPostProcessor 后置和前置处理类似,调用的方法不同。BeanPostProcessor 后置处理调用的是
BeanPostProcessor#postProcessAfterInitialization
1.4、销毁前置处理类注册(Register DisposableBean)
相关的源码
AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary
入口,代码如下public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
// 省略
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
// 省略
}
}
1.5、使用中(In Use)
通过
BeanFactory
直接获取 Bean实例,或者通过@Autowired
等方式使用 IOC 中的 Bean 。
1.6、销毁(Destruction)
继续跟 DisposableBeanAdapter
,代码如下:
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition, List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
// 省略
this.destroyMethod = destroyMethod;
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
@Nullable
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
if (!CollectionUtils.isEmpty(processors)) {
filteredPostProcessors = new ArrayList<>(processors.size());
for (BeanPostProcessor processor : processors) {
if (processor instanceof DestructionAwareBeanPostProcessor) {
DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
if (dabpp.requiresDestruction(bean)) {
filteredPostProcessors.add(dabpp);
}
}
}
}
return filteredPostProcessors;
}
}
销毁的入口源码 AbstractApplicationContext#close
,代码如下:
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
}
}
protected void doClose() {
// Check whether an actual close attempt is necessary...
if (this.active.get() && this.closed.compareAndSet(false, true)) {
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
}
}
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
// Reset local application listeners to pre-refresh state.
if (this.earlyApplicationListeners != null) {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Switch to inactive.
this.active.set(false);
}
}
}
IOC 容器的关闭涉及到 发布关闭事件
、销毁单例Bean
、关闭IOC容器
等操作。
关于 销毁
操作的源码可以追述到 DefaultSingletonBeanRegistry#destroyBean
中,具体代码如下:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// 省略
// Actually destroy the bean now...
if (bean != null) {
try {
// 调用 DisposableBean#destroy 方法
bean.destroy();
}
}
// 省略
}
}
关于 销毁
操作具体可以追溯到 DisposableBeanAdapter#destroy
方法中,代码如下:
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
@Override
public void destroy() {
// 销毁前置处理
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// 省略
if (this.destroyMethod != null) {
// 销毁自定义方法
invokeCustomDestroyMethod(this.destroyMethod);
}
// 省略
}
}
二、案例测试 Bean 生命周期
通过案例验证 Spring Bean 生命周期,包括:
- 实例化
- 属性赋值
- 初始化(各种扩展点的处理)
- 使用中
- DisposableBean 销毁前置处理
- 销毁
整理代码三个类:
BeanLifecycleDemo
用于测试的 class 类BeanLifeCycleDemoConfig
用于注册 class 到IOC的配置类BeanPropertyDemo
用于测试属性赋值的类
2.1、实例化 - 测试代码
在 BeanLifecycleDemo 中
2.2、属性赋值 - 测试代码
涉及到 BeanLifecycleDemo 和 BeanPropertyDemo,主要代码仍在 BeanLifecycleDemo 中
关键代码如下:
使用 setter 注入的方式,埋点打印日志。
2.3、初始化 - 测试代码
代码在 BeanLifecycleDemo 中。
通过实现对应接口,实现对应的方法,并打印日志进行测试,部分关键代码如下:
2.4、使用中 - 测试代码
关键代码在 Spring 容器启动测试代码中,代码逻辑在 BeanLifeCycleDemoConfig#main 方法逻辑中
关键代码如下:
在 Bean 初始化完成后,通过获取Bean 对象,测试其 ToString
方法进行使用测试。
2.5、销毁前置设置 - 测试代码
同初始化处理,通过实现特点接口 DisposableBean 并实现其 DisposableBean#destroy 方法
2.6、销毁 - 测试
通过自定义销毁方法,测试自定义销毁方法的调用,代码在 BeanLifecyleDemo 以及 BeanLifeCycleDemoConfig 中,其中 BeanLifecycleDemo 中自定义了销毁方法,BeanLifeCycleDemoConfig 配置中指定消耗方法为自定义销毁方法。