Spring Bean的生命周期真的是面试的时候关于Spring的最高频的考点之一了,笔者曾经被这个问题问懵了不止一次,一直记不住那一大串的步骤,但实际上尝试去死记硬背那些步骤的我是错误的,表面上看只是背诵一个流程,实际上,这个流程牵扯到的知识点可是很多而且很有意思的。
下面这个图我想很多人应该都看过相同的或者相似的:

看起来还是挺长的对吧,但是我们其实可以把它划分成下面四个大的步骤:
- 实例化Bean
- 设置对象属性,依赖注入
- 初始化
- destroy:bean的销毁
接下来,我会根据这个步骤,一步步的讲解相关的知识点,从生命周期出发,将Spring中重要的类或接口来一一说明。
一、实例化Bean
这第一步,容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入,可以理解成new xx()。但要注意的是,对于BeanFactory容器和ApplicationContext容器它们的实例化是有区别的。
- 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean()进行实例化。
- 对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。
那么既然提到了BeanFactory和ApplicationContext,我就对这两个接口也简单介绍一下。它们分别位于org.springframework.beans和org.springframework.context两个包下,而这两个包,正是Spring IoC容器的基础。BeanFactory提供了框架最基础的一些功能,包括IOC的配置机制,提供Bean的各种定义,建立Bean之间的依赖关系等。ApplicationContext继承了BeanFactory,因此它拥有BeanFactory的所有功能,但它本身还继承了一些其他的接口,比如消息资源配置,事件发布等。
BeanFactory是Spring框架的基础设施,面向Spring。ApplicationContext面向Spring框架的开发者。所以我们平常开发的过程中其实也可以发现到,我们更多的会用上的是ApplicationContext相关的工具,而不是BeanFactory。
除此之外,在实例化这个步骤的前后,实际上还有隐藏任务,牵扯到的接口叫做InstantiationAwareBeanPostProcessor。它继承了BeanPostProcessor。可能有的人不知道BeanPostProcessor这个接口,那么我就先介绍下这个。
BeanPostProcessor也是位于org.springframework.beans下,又叫做后置处理器,它定义了一系列的回调方法用来让使用者可以自定义Bean实例化或者依赖解析等的逻辑。它本身只有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。如方法名所说,定义Bean的初始化前后的逻辑。这个接口在整个生命周期中都有着关联。
1
2
3
4
5
6
7
8
9
10
11
|
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
|
不要弄混了BeanPostProcessor中的方法我说的是初始化前后,而生命周期的第一步是实例化。这里用到的InstantiationAwareBeanPostProcessor它有自己的对于实例化逻辑处理的两个方法。postProcessBeforeInstantiation和postProcessAfterInstantiation。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
}
|
通过查找调用postProcessBeforeInstantiation这个方法的地方,会追溯到创建Bean的关键方法。就是AbstractAutowireCapableBeanFactory下的createBean()。
1
2
3
4
5
6
7
8
9
10
|
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 里面的代码我下面挑出重点的步骤一步步的贴出来
}
|
通过查看源码对于此方法的注释就知道它有多重要了。它可以创建Bean的实例,对其进行属性填充,调用BeanPostProcesser等。第一步我们注意到的代码应该是
1
|
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
|
它实际上是比我们上面生命周期的图示还要之前的一步,就是获取BeanDefinition对象中的信息来对Bean class进行解析。所谓BeanDefinition,它就是对于Bean的一个描述。它包含了Bean的一些基础信息,如Bean的name、Bean的作用域、和其他Bean的关系等等。解析完之后再进行到下一步。
1
2
3
4
5
|
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
|
这个注释其实也给出了它的意义了,它给予BeanPostProcessor们一个机会,可以返回一个代理而不是目标bean的实例。但我们翻阅到上面的InstantiationAwareBeanPostProcessor对于此方法的实现,会发现它返回的是null,所以默认的逻辑这里是不会return的。所以我们会走到下一步,doCreateBean。
1
2
3
4
5
|
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
|
进入到这个方法,它的第一行注释也是简单粗暴,就是来实例化Bean的。
1
2
3
4
5
6
7
8
|
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
|
但可以发现,createBeanInstance()这个方法返回的是一个BeanWrapper对象。BeanWrapper是对Bean的一个包装,它可以设置获取被包装的对象,获取被包装bean的属性描述器等。我们平时开发是不会直接使用这个类的。通过createBeanInstance()这个方法的注释我们也能明白,它的作用是对于指定的bean生成一个新的实例,这里可以使用合适的实例化策略,比如工厂方法,构造器注入或者简单实例化等。
1
2
3
4
5
6
7
|
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//代码我也不贴了
}
|
接下来这段代码,注释也有说明,就是将调用各种postProcessers来进行属性的合并,这里会进行一些注解的扫描。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
|
再然后是一段跟一个面试题紧密相关的代码,那就是Spring如何解决循环依赖。因为本文的重点是讲bean的生命周期,本来准备一起写完的,但写着写着发现要说的太多了,后面我会另外单独写文章来讲述如何解决循环依赖的问题。
1
2
3
4
5
6
7
8
9
10
11
|
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
|
二、设置对象属性,依赖注入
结束了实例化之后,我们继续在createBean这个方法上继续往下走,到了populateBean这一步。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
|
对于这个方法,我们已开始注意到的就是我之前说过在实例化前后都是存在着隐藏任务,上面提到了实例化之前的postProcessBeforeInstantiation,那么如今已经实例化了,现在出现了实例化之后的方法postProcessAfterInstantiation,这里也是给InstantiationAwareBeanPostProcessors一个机会去自定义属性被赋值后的方式。在后面代码中回去执行这个后置处理器的方法。
1
2
3
4
5
6
7
8
9
10
|
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
|
继续往下,我们能看到一个熟悉的单词,Autowire,不过这里是获取当前注入的方式,根据byName还是byType来获得要注入的属性。这里我也不深入说明了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
|
然后就是populateBean的第一步我就提到的方法,如果存在后置处理器,那么会进行属性的校验和处理,同时第二个布尔变量是用来判断是否进行依赖校验的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
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;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
|
最后一步,就是将前面这些步骤得到的属性进行注入了。
1
2
3
|
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
|
三、初始化
populateBean()方法结束后开始进入initializeBean()方法,正如方法名所表达的,就是bean的初始化。注意初始化和实例化不是一个意思,在生命周期中bean是先进行实例化再进行初始化的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
|
首先第一步,先不管那些安全机制的代码,我们要关注的是invokeAwareMethods(beanName, bean);这行代码,这里就是调用所有的Aware类型的接口。Spring中Aware类型的接口可以让我们获取容器中的一些资源。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
|
比如这里面出现的有三种Aware类型的接口: BeanNameAware, BeanClassLoaderAware,BeanFactoryAware。它们根据bean实现了某个接口来完成不同的工作。
- 如果实现了BeanNameAware接口,则通过setBeanName()方法将beanName设置给这个bean
- 如果实现了BeanClassLoaderAware接口,则通过setBeanClassLoader()方法,将ClassLoader传入
- 如果实现了BeanFactoryAware接口,则通过setBeanFactory()方法,将BeanFactory容器实例传入
结束完Aware接口的调用,继续往下走,到了applyBeanPostProcessorsBeforeInitialization()这个方法(因为if判断是这个bean是空或者这个bean是否是synthetic的,就是是否是应用自己定义的,显然我们自己的bean不是,所以if条件后半部分会是true)。这个方法就是处理我之前有提到过的BeanPostProcessor的postProcessBeforeInitialization()方法。如果Bean实现了BeanPostProcessor接口,那么就会执行这个方法。
之后,流程来到了invokeInitMethods()这一步,这一步就是执行bean的自定义初始化方法。如果bean实现了InitializingBean接口,就需要重写**afterPropertiesSet()方法,则invokeInitMethods的时候会调用这个重写后的afterPropertiesSet()**方法,如果bean自定义了init方法,则会调用指定的init方法(可通过xml中配置bean的init-method属性实现),这两个方法的先后顺序是: afterPropertiesSet在前,自定义init在后。
继续下去就是applyBeanPostProcessorsAfterInitialization()方法了,和前面的applyBeanPostProcessorsBeforeInitialization()方法前后呼应,这个就不必多说了。
四、销毁
后面的一段代码还是跟处理循环依赖有关系,就先不多说,直接到最后一步,registerDisposableBeanIfNecessary().
销毁这一步其实就是可以让我们自己自定义bean的销毁方法,用到的关键的接口是DisposableBean,它和InitializingBean接口类似,只是一个初始化阶段的init,一个是结束阶段的destroy。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/**
* Add the given bean to the list of disposable beans in this factory,
* registering its DisposableBean interface and/or the given destroy method
* to be called on factory shutdown (if applicable). Only applies to singletons.
* @param beanName the name of the bean
* @param bean the bean instance
* @param mbd the bean definition for the bean
* @see RootBeanDefinition#isSingleton
* @see RootBeanDefinition#getDependsOn
* @see #registerDisposableBean
* @see #registerDependentBean
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
}
}
|
代码示例
上面一大段一大段的源码可能看着让人有点难受,不如直接写个demo轻松一下。因为只是表现一下生命周期,那么我们的依赖就很简单,spring-context和spring-beans即可。
1
2
3
4
5
6
7
8
9
10
|
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
|
我们先定义一个自定义的后置处理器,为了表现初始化前后和实例化前后的流程,实现InstantiationAwareBeanPostProcessor接口,并重写postProcessBeforeInstantiation()/postProcessAfterInstantiation()/postProcessBeforeInitialization()/postProcessAfterInitialization()这四个方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println(beanName + "实例化前");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "实例化后");
return false;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "初始化前");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "初始化后");
return null;
}
}
|
再定义一个“常规”的Bean,但我们也为了反应初始化和销毁的几个操作,让他实现了InitializingBean, DisposableBean, BeanNameAware三个接口。并实现对应的方法,Aware接口这里我就只实现一个了,只是为了表现注入Aware接口那个步骤。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class DemoBean implements InitializingBean, DisposableBean, BeanNameAware {
public DemoBean() {
System.out.println("demoBean实例化");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("demoBean afterPropertiesSet");
}
public void init() {
System.out.println("demoBean init");
}
@Override
public void destroy() throws Exception {
System.out.println("demoBean destroy");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware setBeanName: "+ s);
}
}
|
配置文件很简单,就两个bean。
1
2
3
4
5
6
7
8
9
10
11
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans>
<bean name="myInstantiationAwareBeanPostProcessor" class="cn.leafw.spring.beans.MyInstantiationAwareBeanPostProcessor" />
<bean name="demoBean" class="cn.leafw.spring.beans.DemoBean" init-method="init">
</bean>
</beans>
</beans>
|
测试类也很简单粗暴,就单纯启动和结束。
1
2
3
4
5
6
7
|
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:application.xml");
applicationContext.registerShutdownHook();
}
}
|
点击运行,接下来就是意料之中的结果输出:

因为属性注入不方便在这里面进行测试,但大家知道是在实例化和初始化之间就好。所以其实总的来说,Spring的生命周期理解起来不算很难,但大家对生命周期里面关键的接口或者类要有印象,ApplicationContext和BeanFactory就不用多说,BeanPostProcessor是一定要知道的,Spring中的很多功能的实现都跟其有关。比如@Autowired注解的原理,数据校验Validate的原理,都是有对应的处理器。
这篇博客写了我挺久的时间,就是越写发现自己对Spring的了解越浅薄,本以为啃完了Spring文档的我应该是能轻松看懂源码,但实际上还是有点吃力的,但看懂了之后真的神清气爽,后面还会继续在这个坑里多填一点东西,学到的越多发现不会的越多,一起进步
Spring源码分析(一) 从Spring Bean的生命周期谈起
Spring Bean的生命周期真的是面试的时候关于Spring的最高频的考点之一了,笔者曾经被这个问题问懵了不止一次,一直记不住那一大串的步骤,但实际上尝试去死记硬背那些步骤的我是错误的,表面上看只是背诵一个流程,实际上,这个流程牵扯到的知识点可是很多而且很有意思的。
下面这个图我想很多人应该都看过相同的或者相似的:

看起来还是挺长的对吧,但是我们其实可以把它划分成下面四个大的步骤:
- 实例化Bean
- 设置对象属性,依赖注入
- 初始化
- destroy:bean的销毁
接下来,我会根据这个步骤,一步步的讲解相关的知识点,从生命周期出发,将Spring中重要的类或接口来一一说明。
一、实例化Bean
这第一步,容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入,可以理解成new xx()。但要注意的是,对于BeanFactory容器和ApplicationContext容器它们的实例化是有区别的。
- 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean()进行实例化。
- 对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。
那么既然提到了BeanFactory和ApplicationContext,我就对这两个接口也简单介绍一下。它们分别位于org.springframework.beans和org.springframework.context两个包下,而这两个包,正是Spring IoC容器的基础。BeanFactory提供了框架最基础的一些功能,包括IOC的配置机制,提供Bean的各种定义,建立Bean之间的依赖关系等。ApplicationContext继承了BeanFactory,因此它拥有BeanFactory的所有功能,但它本身还继承了一些其他的接口,比如消息资源配置,事件发布等。
BeanFactory是Spring框架的基础设施,面向Spring。ApplicationContext面向Spring框架的开发者。所以我们平常开发的过程中其实也可以发现到,我们更多的会用上的是ApplicationContext相关的工具,而不是BeanFactory。
除此之外,在实例化这个步骤的前后,实际上还有隐藏任务,牵扯到的接口叫做InstantiationAwareBeanPostProcessor。它继承了BeanPostProcessor。可能有的人不知道BeanPostProcessor这个接口,那么我就先介绍下这个。
BeanPostProcessor也是位于org.springframework.beans下,又叫做后置处理器,它定义了一系列的回调方法用来让使用者可以自定义Bean实例化或者依赖解析等的逻辑。它本身只有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。如方法名所说,定义Bean的初始化前后的逻辑。这个接口在整个生命周期中都有着关联。
1
2
3
4
5
6
7
8
9
10
11
|
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
|
不要弄混了BeanPostProcessor中的方法我说的是初始化前后,而生命周期的第一步是实例化。这里用到的InstantiationAwareBeanPostProcessor它有自己的对于实例化逻辑处理的两个方法。postProcessBeforeInstantiation和postProcessAfterInstantiation。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
}
|
通过查找调用postProcessBeforeInstantiation这个方法的地方,会追溯到创建Bean的关键方法。就是AbstractAutowireCapableBeanFactory下的createBean()。
1
2
3
4
5
6
7
8
9
10
|
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 里面的代码我下面挑出重点的步骤一步步的贴出来
}
|
通过查看源码对于此方法的注释就知道它有多重要了。它可以创建Bean的实例,对其进行属性填充,调用BeanPostProcesser等。第一步我们注意到的代码应该是
1
|
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
|
它实际上是比我们上面生命周期的图示还要之前的一步,就是获取BeanDefinition对象中的信息来对Bean class进行解析。所谓BeanDefinition,它就是对于Bean的一个描述。它包含了Bean的一些基础信息,如Bean的name、Bean的作用域、和其他Bean的关系等等。解析完之后再进行到下一步。
1
2
3
4
5
|
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
|
这个注释其实也给出了它的意义了,它给予BeanPostProcessor们一个机会,可以返回一个代理而不是目标bean的实例。但我们翻阅到上面的InstantiationAwareBeanPostProcessor对于此方法的实现,会发现它返回的是null,所以默认的逻辑这里是不会return的。所以我们会走到下一步,doCreateBean。
1
2
3
4
5
|
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
|
进入到这个方法,它的第一行注释也是简单粗暴,就是来实例化Bean的。
1
2
3
4
5
6
7
8
|
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
|
但可以发现,createBeanInstance()这个方法返回的是一个BeanWrapper对象。BeanWrapper是对Bean的一个包装,它可以设置获取被包装的对象,获取被包装bean的属性描述器等。我们平时开发是不会直接使用这个类的。通过createBeanInstance()这个方法的注释我们也能明白,它的作用是对于指定的bean生成一个新的实例,这里可以使用合适的实例化策略,比如工厂方法,构造器注入或者简单实例化等。
1
2
3
4
5
6
7
|
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//代码我也不贴了
}
|
接下来这段代码,注释也有说明,就是将调用各种postProcessers来进行属性的合并,这里会进行一些注解的扫描。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
|
再然后是一段跟一个面试题紧密相关的代码,那就是Spring如何解决循环依赖。因为本文的重点是讲bean的生命周期,本来准备一起写完的,但写着写着发现要说的太多了,后面我会另外单独写文章来讲述如何解决循环依赖的问题。
1
2
3
4
5
6
7
8
9
10
11
|
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
|
二、设置对象属性,依赖注入
结束了实例化之后,我们继续在createBean这个方法上继续往下走,到了populateBean这一步。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
|
对于这个方法,我们已开始注意到的就是我之前说过在实例化前后都是存在着隐藏任务,上面提到了实例化之前的postProcessBeforeInstantiation,那么如今已经实例化了,现在出现了实例化之后的方法postProcessAfterInstantiation,这里也是给InstantiationAwareBeanPostProcessors一个机会去自定义属性被赋值后的方式。在后面代码中回去执行这个后置处理器的方法。
1
2
3
4
5
6
7
8
9
10
|
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
|
继续往下,我们能看到一个熟悉的单词,Autowire,不过这里是获取当前注入的方式,根据byName还是byType来获得要注入的属性。这里我也不深入说明了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
|
然后就是populateBean的第一步我就提到的方法,如果存在后置处理器,那么会进行属性的校验和处理,同时第二个布尔变量是用来判断是否进行依赖校验的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
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;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
|
最后一步,就是将前面这些步骤得到的属性进行注入了。
1
2
3
|
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
|
三、初始化
populateBean()方法结束后开始进入initializeBean()方法,正如方法名所表达的,就是bean的初始化。注意初始化和实例化不是一个意思,在生命周期中bean是先进行实例化再进行初始化的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
|
首先第一步,先不管那些安全机制的代码,我们要关注的是invokeAwareMethods(beanName, bean);这行代码,这里就是调用所有的Aware类型的接口。Spring中Aware类型的接口可以让我们获取容器中的一些资源。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
|
比如这里面出现的有三种Aware类型的接口: BeanNameAware, BeanClassLoaderAware,BeanFactoryAware。它们根据bean实现了某个接口来完成不同的工作。
- 如果实现了BeanNameAware接口,则通过setBeanName()方法将beanName设置给这个bean
- 如果实现了BeanClassLoaderAware接口,则通过setBeanClassLoader()方法,将ClassLoader传入
- 如果实现了BeanFactoryAware接口,则通过setBeanFactory()方法,将BeanFactory容器实例传入
结束完Aware接口的调用,继续往下走,到了applyBeanPostProcessorsBeforeInitialization()这个方法(因为if判断是这个bean是空或者这个bean是否是synthetic的,就是是否是应用自己定义的,显然我们自己的bean不是,所以if条件后半部分会是true)。这个方法就是处理我之前有提到过的BeanPostProcessor的postProcessBeforeInitialization()方法。如果Bean实现了BeanPostProcessor接口,那么就会执行这个方法。
之后,流程来到了invokeInitMethods()这一步,这一步就是执行bean的自定义初始化方法。如果bean实现了InitializingBean接口,就需要重写**afterPropertiesSet()方法,则invokeInitMethods的时候会调用这个重写后的afterPropertiesSet()**方法,如果bean自定义了init方法,则会调用指定的init方法(可通过xml中配置bean的init-method属性实现),这两个方法的先后顺序是: afterPropertiesSet在前,自定义init在后。
继续下去就是applyBeanPostProcessorsAfterInitialization()方法了,和前面的applyBeanPostProcessorsBeforeInitialization()方法前后呼应,这个就不必多说了。
四、销毁
后面的一段代码还是跟处理循环依赖有关系,就先不多说,直接到最后一步,registerDisposableBeanIfNecessary().
销毁这一步其实就是可以让我们自己自定义bean的销毁方法,用到的关键的接口是DisposableBean,它和InitializingBean接口类似,只是一个初始化阶段的init,一个是结束阶段的destroy。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/**
* Add the given bean to the list of disposable beans in this factory,
* registering its DisposableBean interface and/or the given destroy method
* to be called on factory shutdown (if applicable). Only applies to singletons.
* @param beanName the name of the bean
* @param bean the bean instance
* @param mbd the bean definition for the bean
* @see RootBeanDefinition#isSingleton
* @see RootBeanDefinition#getDependsOn
* @see #registerDisposableBean
* @see #registerDependentBean
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
}
}
|
代码示例
上面一大段一大段的源码可能看着让人有点难受,不如直接写个demo轻松一下。因为只是表现一下生命周期,那么我们的依赖就很简单,spring-context和spring-beans即可。
1
2
3
4
5
6
7
8
9
10
|
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
|
我们先定义一个自定义的后置处理器,为了表现初始化前后和实例化前后的流程,实现InstantiationAwareBeanPostProcessor接口,并重写postProcessBeforeInstantiation()/postProcessAfterInstantiation()/postProcessBeforeInitialization()/postProcessAfterInitialization()这四个方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println(beanName + "实例化前");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "实例化后");
return false;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "初始化前");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "初始化后");
return null;
}
}
|
再定义一个“常规”的Bean,但我们也为了反应初始化和销毁的几个操作,让他实现了InitializingBean, DisposableBean, BeanNameAware三个接口。并实现对应的方法,Aware接口这里我就只实现一个了,只是为了表现注入Aware接口那个步骤。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class DemoBean implements InitializingBean, DisposableBean, BeanNameAware {
public DemoBean() {
System.out.println("demoBean实例化");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("demoBean afterPropertiesSet");
}
public void init() {
System.out.println("demoBean init");
}
@Override
public void destroy() throws Exception {
System.out.println("demoBean destroy");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware setBeanName: "+ s);
}
}
|
配置文件很简单,就两个bean。
1
2
3
4
5
6
7
8
9
10
11
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans>
<bean name="myInstantiationAwareBeanPostProcessor" class="cn.leafw.spring.beans.MyInstantiationAwareBeanPostProcessor" />
<bean name="demoBean" class="cn.leafw.spring.beans.DemoBean" init-method="init">
</bean>
</beans>
</beans>
|
测试类也很简单粗暴,就单纯启动和结束。
1
2
3
4
5
6
7
|
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:application.xml");
applicationContext.registerShutdownHook();
}
}
|
点击运行,接下来就是意料之中的结果输出:

因为属性注入不方便在这里面进行测试,但大家知道是在实例化和初始化之间就好。所以其实总的来说,Spring的生命周期理解起来不算很难,但大家对生命周期里面关键的接口或者类要有印象,ApplicationContext和BeanFactory就不用多说,BeanPostProcessor是一定要知道的,Spring中的很多功能的实现都跟其有关。比如@Autowired注解的原理,数据校验Validate的原理,都是有对应的处理器。
这篇博客写了我挺久的时间,就是越写发现自己对Spring的了解越浅薄,本以为啃完了Spring文档的我应该是能轻松看懂源码,但实际上还是有点吃力的,但看懂了之后真的神清气爽,后面还会继续在这个坑里多填一点东西,学到的越多发现不会的越多,一起进步
The following diagram is probably something many people have seen the same or similar:

It looks quite long right? But we can actually divide it into the following four main steps:
- Bean instantiation
- Setting bean properties, dependency injection
- Initialization
- Destroy: bean destruction
Next, I will explain the related knowledge points step by step according to this process, starting from the lifecycle.
1. Bean Instantiation
In this first step, the container instantiates by obtaining information from the BeanDefinition object. And this step is just simple instantiation, no dependency injection, which can be understood as new xx(). But note that there are differences in instantiation between BeanFactory containers and ApplicationContext containers.
- For the BeanFactory container, when the customer requests a bean that has not yet been initialized to the container, or when injecting another uninitialized dependency when initializing the bean, the container will call createBean() for instantiation.
- For the ApplicationContext container, it instantiates all beans after the container startup ends.
Now that BeanFactory and ApplicationContext have been mentioned, let me briefly introduce these two interfaces as well. They are located under org.springframework.beans and org.springframework.context respectively. These two packages are the basis for Spring IoC containers. BeanFactory provides some of the most basic features of the framework, including IoC configuration mechanisms, various bean definitions, establishing dependencies between beans, etc. ApplicationContext inherits from BeanFactory, so it has all the functionality of BeanFactory, but it also inherits some other interfaces, such as message resource configuration, event publishing, etc.
BeanFactory is the basic infrastructure of the Spring framework, facing Spring. ApplicationContext faces Spring framework developers. So we can also find that in the development process, we will actually use ApplicationContext related tools more, rather than BeanFactory.
In addition, before and after this instantiation step, there are actually hidden tasks involving the interface called InstantiationAwareBeanPostProcessor. It inherits from BeanPostProcessor. Some people may not know the BeanPostProcessor interface, so let me introduce it first.
BeanPostProcessor, also known as post processor, is also located under org.springframework.beans. It defines a series of callback methods for users to customize logic for Bean instantiation or dependency resolution. It itself only has two methods: postProcessBeforeInitialization and postProcessAfterInitialization. As the method name implies, it defines the logic before and after initialization of the Bean. This interface is associated throughout the entire lifecycle.
1
2
3
4
5
6
7
8
9
10
11
|
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
|
Don’t confuse the methods in BeanPostProcessor that I said are for initialization before and after, while the first step in the lifecycle is instantiation. The InstantiationAwareBeanPostProcessor used here has its own two methods for processing instantiation logic. postProcessBeforeInstantiation and postProcessAfterInstantiation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
}
|
By looking up where the postProcessBeforeInstantiation method is called, it will trace back to the key method for creating beans. That is createBean() under AbstractAutowireCapableBeanFactory.
1
2
3
4
5
6
7
8
9
10
|
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//
}
|
From the comments on this method, we can see how important it is. It can create bean instances, populate them with properties, call BeanPostProcessers, etc. The first step we should pay attention to is:
1
|
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
|
It is actually a step earlier than our lifecycle diagram above. It is to parse the bean class information from the BeanDefinition object. The so-called BeanDefinition is a description of the Bean. It contains some basic information about the Bean, such as the Bean’s name, scope, relationships with other Beans, etc. After parsing, move on to the next step.
1
2
3
4
5
|
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
|
The comments here also give its meaning. It gives BeanPostProcessors a chance to return a proxy instead of the target bean instance. But when we look up the implementation of this method for InstantiationAwareBeanPostProcessor, we will find that it returns null, so the default logic here will not return. So we will go to the next step, doCreateBean.
1
2
3
4
5
|
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
|
Entering this method, the first line of comments is simple and crude, which is to instantiate the Bean.
1
2
3
4
5
6
7
8
|
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
|
But we can see that the createBeanInstance() method returns a BeanWrapper object. BeanWrapper is a wrapper for the Bean, which can set/get the wrapped object and get the property descriptor of the wrapped bean. We don’t usually use this class directly when developing. From the comments of the createBeanInstance() method we can also understand that its role is to generate a new instance of the specified bean, where appropriate instantiation strategies can be used, such as factory methods, constructor injection, or simple instantiation, etc.
1
2
3
4
5
6
7
|
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
}
|
The following code, the comments also explain, is to call various postProcessers for attribute merging, where some annotation scanning will be done.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
|
Then there is a section of code that is closely related to an interview question, which is how Spring solves circular dependencies. Because the focus of this article is to explain the bean lifecycle, I was going to finish writing it together, but found that there was too much to say. I will write a separate article later to explain how to solve circular dependency issues.
1
2
3
4
5
6
7
8
9
10
11
|
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
|
2. Setting Bean Properties, Dependency Injection
After instantiation is complete, we continue down the createBean method to the next step, populateBean.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
|
For this method, what we start to notice is what I said earlier, that there are hidden tasks before and after instantiation. The postProcessBeforeInstantiation() method mentioned above appears before instantiation, and now the bean has been instantiated, so the postProcessAfterInstantiation() method after instantiation appears, which also gives InstantiationAwareBeanPostProcessors a chance to customize the way properties are assigned after instantiation. The method of the post processor will be executed later in the code.
1
2
3
4
5
6
7
8
9
10
|
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
|
Going down, we can see a familiar word, Autowire, but here it is getting the current injection mode, according to byName or byType to get the properties to inject. I won’t go into detail here.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
|
Then the first step I mentioned in populateBean is the method that if there are post processors, attribute validation and processing will be performed, and the second boolean variable is used to determine whether to perform dependency validation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
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;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
|
The last step is to inject the properties obtained from the previous steps.
1
2
3
|
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
|
3. Initialization
After the populateBean() method, it enters the initializeBean() method, which, as the method name expresses, is the initialization of the bean. Note that initialization and instantiation are not the same, the bean is instantiated first and then initialized in the lifecycle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
|
First, disregarding the security mechanism code, what we need to pay attention to is invokeAwareMethods(beanName, bean); This line of code is where all Aware type interfaces are called. Spring Aware type interfaces allow us to obtain some resources in the container.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
|
For example, there are three types of Aware interfaces here: BeanNameAware, BeanClassLoaderAware, BeanFactoryAware. They do different work according to whether the bean implements a certain interface.
- If BeanNameAware is implemented, the beanName is set to this bean through the setBeanName() method
- If BeanClassLoaderAware is implemented, the ClassLoader is passed through the setBeanClassLoader() method
- If BeanFactoryAware is implemented, the BeanFactory container instance is passed through the setBeanFactory() method
After completing the call to the Aware interface, continue down to the applyBeanPostProcessorsBeforeInitialization() method (because the if judgment is whether this bean is empty or whether this bean is synthetic, that is, whether it is defined by the application itself, obviously our own beans are not, so the second half of the if condition will be true). This method handles the BeanPostProcessor’s postProcessBeforeInitialization() method. If the Bean implements the BeanPostProcessor interface, this method will be executed.
After that, the process comes to invokeInitMethods() step, which is to execute the custom initialization method of the bean. If the bean implements the InitializingBean interface, you need to override the afterPropertiesSet() method, then invokeInitMethods() will call this overridden afterPropertiesSet() method. If the bean has a custom init method, the specified init method will be called (can be configured through the init-method attribute of the bean in xml), the order of these two methods is: afterPropertiesSet first, custom init second.
Going down is the applyBeanPostProcessorsAfterInitialization() method, which echoes the previous applyBeanPostProcessorsBeforeInitialization() method, no need to elaborate.
4. Destruction
The following section of code is still related to handling circular dependencies, so I won’t go into details for now, go directly to the last step, registerDisposableBeanIfNecessary().
Destruction allows us to customize the bean’s destruction method. The key interface used is DisposableBean, which is similar to the InitializingBean interface. One is the init phase and the other is the destroy phase at the end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/**
* Add the given bean to the list of disposable beans in this factory,
* registering its DisposableBean interface and/or the given destroy method
* to be called on factory shutdown (if applicable). Only applies to singletons.
* @param beanName the name of the bean
* @param bean the bean instance
* @param mbd the bean definition for the bean
* @see RootBeanDefinition#isSingleton
* @see RootBeanDefinition#getDependsOn
* @see #registerDisposableBean
* @see #registerDependentBean
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
}
}
|
Code Example
The long sections of source code above may be a bit difficult to digest, so it’s better to write a demo to relax. Since it is just to show the lifecycle, the dependencies are very simple, just spring-context and spring-beans.
1
2
3
4
5
6
7
8
9
10
|
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
|
First we define a custom post processor. In order to show the process before and after initialization and instantiation, implement the InstantiationAwareBeanPostProcessor interface and override postProcessBeforeInstantiation()/postProcessAfterInstantiation()/postProcessBeforeInitialization()/postProcessAfterInitialization() these four methods.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println(beanName + "实例化前");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "实例化后");
return false;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "初始化前");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "初始化后");
return null;
}
}
|
Then define a “normal” Bean, but in order to reflect the initialization and destruction operations, let it implement InitializingBean, DisposableBean, BeanNameAware three interfaces. And implement the corresponding methods. Implement only one of the Aware interfaces here, just to demonstrate the step of injecting the Aware interface.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class DemoBean implements InitializingBean, DisposableBean, BeanNameAware {
public DemoBean() {
System.out.println("demoBean实例化");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("demoBean afterPropertiesSet");
}
public void init() {
System.out.println("demoBean init");
}
@Override
public void destroy() throws Exception {
System.out.println("demoBean destroy");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware setBeanName: "+ s);
}
}
|
The configuration file is very simple, just two beans.
1
2
3
4
5
6
7
8
9
10
11
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans>
<bean name="myInstantiationAwareBeanPostProcessor" class="cn.leafw.spring.beans.MyInstantiationAwareBeanPostProcessor" />
<bean name="demoBean" class="cn.leafw.spring.beans.DemoBean" init-method="init">
</bean>
</beans>
</beans>
|
The test class is also very simple, just starting and ending.
1
2
3
4
5
6
7
|
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:application.xml");
applicationContext.registerShutdownHook();
}
}
|
Click to run, then the expected results are output:

Because property injection is not easy to test here, just know that it is between instantiation and initialization. So in general, understanding the Spring lifecycle is not too difficult, but you should be familiar with the key interfaces or classes in the lifecycle. ApplicationContext and BeanFactory need no introduction. BeanPostProcessor must be known, many Spring features are implemented with it. Such as the principle of @Autowired annotation, data validation Validate, etc., there are corresponding handlers.
It took me quite a long time to write this blog. The more I wrote, the more I realized how shallow my understanding of Spring was. I thought I had chewed through the Spring documentation and should be able to easily understand the source code, but it was actually a bit difficult. But after understanding it, it really feels great. I will continue to fill in more things in this pit afterwards. The more I learn, the more I realize I don’t know, let’s improve together!
