Spring Bean的生命周期:从源码层面进行全解析

Spring Bean的生命周期:从源码层面进行全解析

一、引言

在Spring框架中,有一个核心概念贯穿始终——Bean。如果说Spring是一个微型的操作系统,那么Bean就是运行在这个系统里的进程。控制反转(IoC)使得Spring容器取代了开发者,成为对象的管理者。

对于很多开发者而言,“Bean生命周期”意味着背下一堆接口名和顺序。但仅仅记住顺序是苍白的,我们真正需要理解的是:

  • Bean究竟是在哪一行代码被new出来的?
  • 属性注入是如何通过反射写入字段的?
  • BeanPostProcessor的调用栈到底长什么样?
  • 循环依赖是如何通过三级缓存“瞒天过海”的?

本文将带你逐行调试Spring源码(基于Spring 5.3.x),从AbstractApplicationContextrefresh()方法开始,彻底吃透Bean的生命周期。

二、生命周期全景图

在深入源码之前,我们先从宏观上俯瞰一个Bean的“一生”。通常,我们可以将一个Bean的生命周期划分为四个主要阶段,但在源码层面,它可以被细化为以下步骤:

  1. 实例化:为Bean分配内存空间(类似于new关键字)。
  2. 属性赋值:填充Bean的各种属性(依赖注入)。
  3. 初始化
    • 调用各种Aware接口(BeanNameAwareBeanFactoryAware等)。
    • 执行BeanPostProcessor的前置处理。
    • 调用初始化方法(@PostConstructInitializingBeaninit-method)。
    • 执行BeanPostProcessor的后置处理(这里是AOP动态代理的常见介入点)。
  4. 销毁:容器关闭时,清理资源。

接下来,我们将围绕着Spring IOC的核心方法——refresh(),来逐一挖掘这些步骤背后的源码实现。

生命周期全景图核心流程

三、源码入口:一切始于 refresh()

无论是XML配置还是注解配置,Spring的启动入口最终都会落到AbstractApplicationContextrefresh()方法。这是Spring IOC容器的“心脏”。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// AbstractApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新:设置启动时间、设置活动标志等。
prepareRefresh();

// 2. ★ 关键点:获取新的BeanFactory,加载Bean定义 ★
// 这一步会解析配置(XML/注解),生成BeanDefinition,并注册到BeanFactory。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 3. 准备BeanFactory,设置类加载器,添加一些内置的BeanPostProcessor等。
prepareBeanFactory(beanFactory);

try {
// 4. 允许子类在BeanFactory初始化完毕后进行后置处理。
postProcessBeanFactory(beanFactory);

// 5. ★ 调用BeanFactoryPostProcessor,对BeanDefinition进行修改 ★
invokeBeanFactoryPostProcessors(beanFactory);

// 6. ★ 注册BeanPostProcessor,等待在Bean初始化前后执行 ★
registerBeanPostProcessors(beanFactory);

// 7. 初始化消息源(国际化相关)
initMessageSource();

// 8. 初始化应用事件广播器
initApplicationEventMulticaster();

// 9. 留给子类的扩展点:刷新容器时初始化特定的Bean
onRefresh();

// 10. 注册监听器
registerListeners();

// 11. ★ 核心:完成BeanFactory的初始化,实例化所有非懒加载的单例Bean ★
finishBeanFactoryInitialization(beanFactory);

// 12. 发布容器刷新完成事件
finishRefresh();
} catch (BeansException ex) {
// 异常处理,销毁已创建的Bean
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
// 重置公共缓存
resetCommonCaches();
}
}
}

refresh()的12个步骤中,真正触发“Bean生命周期”的核心步骤是第11步:finishBeanFactoryInitialization(beanFactory)

四、实例化前置:BeanDefinition 的加载

​ 在Bean实例化之前,Spring需要知道怎么“造”这个Bean,这个蓝图就是BeanDefinition。它包含了类的全限定名、作用域、懒加载设置、构造参数、属性值等信息。

obtainFreshBeanFactory()方法会触发BeanDefinition的加载。以注解方式为例,ClassPathBeanDefinitionScanner会扫描指定包下的类,将它们包装成ScannedGenericBeanDefinition,最终注册到DefaultListableBeanFactorybeanDefinitionMap中。

1
2
3
// DefaultListableBeanFactory.java
// 核心存储:key是beanName,value是BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

此时,Bean还没有实例化,只是“图纸”已经准备好了。

五、核心剖析:finishBeanFactoryInitialization

该方法会实例化所有剩余的非懒加载单例Bean。我们进入源码:

1
2
3
4
5
6
7
// DefaultListableBeanFactory.java
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// ... 转换器等准备操作

// ★ 核心:实例化所有剩下的单例Bean
beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons方法会遍历beanDefinitionMap中的所有beanName,依次调用getBean(beanName)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// DefaultListableBeanFactory.java
@Override
public void preInstantiateSingletons() throws BeansException {
// 创建一个副本,避免并发修改异常
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// ★ 触发所有非懒加载单例Bean的实例化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果是FactoryBean,特殊处理
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// ...
} else {
// ★ 普通Bean:调用getBean触发创建
getBean(beanName);
}
}
}
// ... 所有Bean实例化完毕后,触发SmartInitializingSingleton回调
}

可以看到,无论哪种Bean,最终都逃不过getBean()。而getBean()BeanFactory接口定义的最基础方法,其实现位于AbstractBeanFactory

六、源码深潜:doGetBeancreateBean

getBean()是一个模板方法,真正的创建逻辑在createBean中。

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
34
35
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
// 1. ★ 尝试从单例缓存中获取Bean(这里是解决循环依赖的关键) ★
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 如果找到了,处理FactoryBean的情况,直接返回
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 2. 如果没有,则标记当前Bean正在创建中(用于解决循环依赖)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// 3. 递归处理父BeanFactory
if (!this.beanFactory.containsBeanDefinition(beanName)) {
// ...
}

// 4. 标记当前Bean正在创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

try {
// 5. ★ 合并父BeanDefinition ★
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

// 6. ★ 触发Bean的创建(核心逻辑) ★
bean = createBean(beanName, mbd, args);
} catch (Exception ex) {
// ...
}
}
return (T) bean;
}

createBeanAbstractAutowireCapableBeanFactory实现,这里包含了生命周期的全部奥秘。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

// 1. 给BeanPostProcessor一个机会,返回代理对象(如AOP)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean; // 若InstantiationAwareBeanPostProcessor直接返回了代理对象,则短路操作
}

// 2. 如果前置处理没有返回代理,则执行真正的创建流程
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}

七、生命周期全流程:doCreateBean

这里就是Bean诞生的“产房”了。我将doCreateBean方法拆解为实例化 -> 属性填充 -> 初始化三大步。

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
34
35
36
37
38
39
40
41
42
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// 1. ★ 实例化(Instantiation)★
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 核心:通过构造函数或工厂方法创建实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();

// 2. 如果是单例,将提前暴露的ObjectFactory放入缓存(解决循环依赖的关键)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// 3. ★ 属性赋值(Populate Properties)★
try {
populateBean(beanName, mbd, instanceWrapper);
} catch (Throwable ex) {
// ...
}

// 4. ★ 初始化(Initialization)★
Object exposedObject = bean;
try {
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
// ...
}

// 5. 注册销毁方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);

return exposedObject;
}

7.1 实例化:createBeanInstance

这一步是通过反射创建JVM对象。

1
2
3
4
5
6
7
8
9
10
11
12
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 检查是否有工厂方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// 如果有多个构造函数,进行解析推断
// ...

// 默认使用无参构造函数实例化
return instantiateBean(beanName, mbd);
}

instantiateBean最终会通过SimpleInstantiationStrategy使用BeanUtils.instantiateClass(constructor, args)来创建对象。此时,Bean对象已经被new出来了,但属性还都是null。

7.2 属性赋值: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
29
30
31
32
33
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 在属性赋值前,调用 InstantiationAwareBeanPostProcessor 的后置处理器
// 例如:@Autowired 的注入逻辑就发生在这里
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 如果返回false,则跳过属性填充
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}

// 获取属性值(依赖)
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

// 处理依赖注入(@Autowired、@Value、@Resource)
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 调用 postProcessProperties 进行属性注入(如 AutowiredAnnotationBeanPostProcessor)
pvs = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}

// 应用属性值(例如XML配置的property标签)
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}

关键点:我们常用的@Autowired注解,就是由AutowiredAnnotationBeanPostProcessor在这里通过反射将依赖注入进去的。

7.3 初始化:initializeBean

这是回调最多、逻辑最复杂的部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// ★ 第一部分:调用 Aware 接口 ★
invokeAwareMethods(beanName, bean);

// ★ 第二部分:初始化前(BeanPostProcessor 前置处理) ★
Object wrappedBean = bean;
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

// ★ 第三部分:调用初始化方法 ★
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
// ...
}

// ★ 第四部分:初始化后(BeanPostProcessor 后置处理 - AOP动态代理的常见发生点) ★
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

return wrappedBean;
}

7.3.1 回调 Aware 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

注意ApplicationContextAware并不是在这里调用的!它是由ApplicationContextAwareProcessor这个特殊的BeanPostProcessor调用的。该处理器在prepareBeanFactory步骤中被添加到容器中,因此会在接下来的applyBeanPostProcessorsBeforeInitialization中执行。

7.3.2 初始化前置处理

1
2
3
4
5
6
7
8
9
10
11
12
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

在这里,ApplicationContextAwareProcessor被执行,@PostConstruct注解的方法(由CommonAnnotationBeanPostProcessor处理)也在这里被执行。

7.3.3 调用初始化方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {

// 1. 如果实现了 InitializingBean,调用 afterPropertiesSet()
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && !(mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
((InitializingBean) bean).afterPropertiesSet();
}

// 2. 调用自定义的 init-method(如果指定的话)
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName))) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}

7.3.4 初始化后置处理

1
2
3
4
5
6
7
8
9
10
11
12
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

这是Spring AOP发生的关键地点AbstractAutoProxyCreator(一个BeanPostProcessor)会在postProcessAfterInitialization中检查当前Bean是否满足切面拦截条件。如果满足,就会使用动态代理(JDK或CGLIB)创建一个代理对象返回。此时,exposedObject就不再是原始Bean,而是代理对象了。

7.4 注册销毁方法

1
2
3
4
5
6
7
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
if (mbd.isSingleton() && !mbd.isLazyInit()) {
// 将Bean包装为DisposableBeanAdapter,注册到内部集合中
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors()));
}
}

容器关闭时,会遍历这个集合,依次调用销毁方法(顺序:@PreDestroy -> DisposableBean.destroy() -> destroy-method)。

八、核心组件与执行时机源码

核心组件与执行时机

生命周期阶段 源码位置(类/方法) 核心接口/注解 调用时机
实例化 AbstractAutowireCapableBeanFactory.doCreateBean() -> createBeanInstance() 构造函数 通过反射创建对象,属性为空
属性注入 AbstractAutowireCapableBeanFactory.populateBean() @Autowired, @Resource, @Value 填充属性,执行依赖注入
Aware接口(部分) AbstractAutowireCapableBeanFactory.invokeAwareMethods() BeanNameAware, BeanFactoryAware 设置Bean名称、工厂等
BeanPostProcessor前置 applyBeanPostProcessorsBeforeInitialization() BeanPostProcessor.postProcessBeforeInitialization 初始化前回调,如@PostConstruct
初始化 invokeInitMethods() InitializingBean.afterPropertiesSet(), @Bean(initMethod) 执行自定义初始化逻辑
BeanPostProcessor后置 applyBeanPostProcessorsAfterInitialization() BeanPostProcessor.postProcessAfterInitialization AOP动态代理介入点
就绪 - - Bean存入一级缓存singletonObjects
销毁 DisposableBeanAdapter.destroy() @PreDestroy, DisposableBean, @Bean(destroyMethod) 容器关闭时清理资源

九、总结

​ Spring Bean的生命周期并不是一堆零散概念的堆砌,而是一个高度严谨、设计精巧的执行流程。它从BeanDefinition的加载开始,经历了构造函数反射的实例化、属性依赖的注入、Aware接口的回调、BeanPostProcessor在初始化前后的拦截,最终以@PostConstructinit-method收尾,成为一个可用的Bean,并在容器关闭时以约定的顺序优雅销毁。


Spring Bean的生命周期:从源码层面进行全解析
https://johnjoyjzw.github.io/2024/11/08/SpringBean的生命周期-从源码层面进行全解析/
Author
JiangZW
Posted on
November 8, 2024
Licensed under