SpringBean生命周期
读源码小方法:先把所有代码块折叠,看整体,再逐步进入局部,忽略异常处理。写简单程序打断点调试。
结论
- 生命周期主要的扩展点:实例化(
doGetBean()->createBeanInstance()
),注入(populate
),初始化(initializeBean
),销毁。一般processor都是在这些点前后扩展。 - 初始化容器的时候会把实现了
BeanFactoryPostProcessor BeanPostProcessor
等接口的bean实例化(不管有没有设置lazy-init),前者会在BeanDefinition
加载完成后被调用,用于编辑BeanDefinition。后者的方法会在后续每一个bean的实例化前后被调用,而其子接口InstantiationAwareBeanPostProcessor
的方法会在初始化前后和设置注入属性前被调用。 - 命名中有Aware的接口比如:
BeanFactoryAware,BeanNameAware
用于bean在创建过程注入对应的容器资源,每个bean的这些方法只会在自己创建的时候被调用。 - 配置的
init-method destory-method
也只会在自己创建的时候被调用。DisposableBean,InitializingBean
也是。 - 以上并没有说明他们的顺序,顺序如下图,但实际上在一个bean创建过程中不一定所有方法都会执行。后面的代码分析中会仔细分析。
- 分析生命周期还得结合实际用途,不然会很疑惑他们有什么用,一般和AOP之类的有关,后面再分析
代码&&分析
下面将从几个扩展点介绍相应的Procesor,并且说明他们返回值对后面流程的影响及其原因(结论+代码分析)。
其实很多类、接口、方法写了详细的说明和注释,表明有什么作用。
初始化容器阶段
在AbstractApplicationContext#refresh()
中,以下三个函数
第一个函数本类没有实现,让子类自由发挥,比如加一些BeanPostProcessors
。但是子类似乎也没实现
This template method allows for registering special BeanPostProcessors etc in certain AbstractApplicationContext subclasses.
这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事。ref
第二个注册,实例化,并且调用BeanFactoryPostProcessor
实现类的方法
Instantiate and invoke all registered BeanFactoryPostProcessor beans, respecting explicit order if given.
第三个注册和实例化BeanPostProcess
Instantiate and register all BeanPostProcessor beans, respecting explicit order if given
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
注意补充
后来才发现在上面三个函数上面还有一个函数调用
prepareBeanFactory(beanFactory);
这个是提前注册了一些BeanPostProcessor
在里面,比如ApplicationContextAwareProcessor
,他的功能主要是给这些接口注入application的一些信息,他会在postProcessBeforeInitialization
函数中调用这个函数。
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) //后续省略
if (bean instanceof ResourceLoaderAware)
if (bean instanceof ApplicationEventPublisherAware)
if (bean instanceof MessageSourceAware)
if (bean instanceof ApplicationStartupAware)
if (bean instanceof ApplicationContextAware)
}
类似的提前注入的BeanPostProcessor
还有
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
Bean生命周期
总体逻辑图
先给流程,后面的分析就是贴代码说原因。
其实xx前xx后不一定就紧跟着xx,比如实例化后的执行实际不是紧跟着实例化,而是在注入之前。
实例化
入口是AbstractAutowireCapableBeanFactory#createBean()
,内部关键函数调用resolveBeforeInstantiation() doCreateBean()
,这两个都有实例化功能。其中doGetBean
内部进一步执行后面两个阶段(注入,初始化)的函数。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//************实例化前****************
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//************初始化后****************
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
出来之后,如果返回就没有后面的doGetBean()
了
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
注入属性
AbstractAutowireCapableBeanFactory#populateBean()
实例化后
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 实例化后的返回值影响是否依赖注入
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
注入属性前
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
//***************处理属性
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//*****************处理属性值**********返回值影响是否进行依赖注入
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
初始化
AbstractAutowireCapableBeanFactory#initializeBean()
// 省略次要代码
// 调用Aware接口的代码,注意
invokeAwareMethods(beanName, bean);
// InitializingBean#afterProperties 和 Init-method
invokeInitMethods(beanName, wrappedBean, mbd);
//...
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//...
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
这几行代码中的逻辑都不影响后续执行,其中,第一个内部是这样:
// 省略次要代码
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware)//....
if (bean instanceof BeanClassLoaderAware)
if (bean instanceof BeanFactoryAware)
}
注意,上面 [初始化容器阶段的注意补充](# 初始化容器阶段) 中讲了,有些Aware接口的方法是在
ApplicationContextAwareProcessor
的postProcessBeforeInitialization
, 初始化前的方法中调用的。也就是说这些Aware是在上述四行代码中的第三行中调用的。
第二个内部是这样
// InitializingBean接口
((InitializingBean) bean).afterPropertiesSet();
// 如果配置的initMethod和上面那个名字不一样就执行initMethod
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
后面两个就是遍历执行processor的方法了没什么好说的。
注册为DisposableBean
AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary()
无processor调用,如果实现了DisposableBean()
会注册进去。他的destory()
在配置的destory-method
方法之前执行,和初始化那个顺序一样。
常用生命周期接口
从上面的分析也能看出来有哪些了。
只调用一次的,用于编辑Factory中的BeanDefinition
的
BeanFactoryPostProcessor()
在每个Bean的生命周期中调用
BeanPostProcessor && InstantiationAwareBeanPostProcessor
后者继承前者,前者只有实例化前后的两个方法,后者多了初始化前后和设置属性值之前的两个方法,一共多了四个
Aware类
有两类,上面也说了。一般这种接口要获取的东西在名字已经体现得很好了。
第一类:BeanNameAware, BeanClassLoader
等
第二类:EnvironmentAware, ApplicationContextAware
等
初始化和销毁
InitializingBean && DisposableBean
配置的初始方法和销毁方法
就是init-method destory-method
,注意如果这两个方法和上一种接口的方法是重复的,那么这个不会执行。
实际用途
不同的地方有很多不同的扩展,给用户很大操作空间。据说AOP和BeanPostProcessor
有很大关系,等到分析AOP原理的时候在讨论这个。