文章目录
-
- 一、阶段定位与重要性
- 二、源码级执行流程
- 三、Bean实例化九步曲
-
- [1. 实例化对象(createBeanInstance)](#1. 实例化对象(createBeanInstance))
- [2. 处理合并定义(applyMergedBeanDefinitionPostProcessors)](#2. 处理合并定义(applyMergedBeanDefinitionPostProcessors))
- [3. 暴露早期引用(addSingletonFactory)](#3. 暴露早期引用(addSingletonFactory))
- [4. 属性填充(populateBean)](#4. 属性填充(populateBean))
- [5. Aware接口回调(invokeAwareMethods)](#5. Aware接口回调(invokeAwareMethods))
- [6. 初始化前处理(applyBeanPostProcessorsBeforeInitialization)](#6. 初始化前处理(applyBeanPostProcessorsBeforeInitialization))
- [7. 执行初始化(invokeInitMethods)](#7. 执行初始化(invokeInitMethods))
- [8. 初始化后处理(applyBeanPostProcessorsAfterInitialization)](#8. 初始化后处理(applyBeanPostProcessorsAfterInitialization))
- [9. 注册销毁方法(registerDisposableBean)](#9. 注册销毁方法(registerDisposableBean))
- 四、循环依赖解决机制
-
- [1. 为什么需要三级缓存?](#1. 为什么需要三级缓存?)
- [2. 二级缓存的作用](#2. 二级缓存的作用)
- 五、性能优化策略
- 六、常见问题排查
-
- [1. Bean创建失败场景](#1. Bean创建失败场景)
- [2. 性能问题定位](#2. 性能问题定位)
- 七、最佳实践总结
深入Spring心脏,揭秘单例Bean实例化的完整生命周期
在Spring框架中,finishBeanFactoryInitialization(beanFactory)
是整个IOC容器启动过程中最核心、最重量级 的阶段。这个阶段负责实例化、初始化和装配所有非延迟加载的单例Bean,通常消耗整个启动过程70%以上的时间。理解这个阶段的内部机制,对于掌握Spring框架精髓、优化应用性能至关重要。
一、阶段定位与重要性
在容器启动中的位置

核心职责
- 实例化所有非延迟加载的单例Bean
- 解决Bean之间的循环依赖
- 执行依赖注入(DI)
- 触发Bean的生命周期回调
- 生成AOP代理对象
二、源码级执行流程
入口方法:finishBeanFactoryInitialization()

核心方法:preInstantiateSingletons()
总的来说,getBean() 方法是依赖注入的起点,之后会调用 createBean()
,根据之前解析生成的 BeanDefinition
对象 生成 bean 对象,下面我们看看 AbstractBeanFactory
的子类 AbstractAutowireCapableBeanFactory
中对 createBean()
的具体实现。
三、Bean实例化九步曲
当调用getBean(beanName)
时,最终会执行doCreateBean()
方法,这是Bean实例化的核心流程:
1. 实例化对象(createBeanInstance)
Spring通过多种策略创建Bean实例:
默认构造函数实例化:

2. 处理合并定义(applyMergedBeanDefinitionPostProcessors)
允许MergedBeanDefinitionPostProcessor
后处理器修改合并后的Bean定义:
典型应用:
AutowiredAnnotationBeanPostProcessor
:查找@Autowired
和@Value
注解CommonAnnotationBeanPostProcessor
:查找@PostConstruct
和@PreDestroy
注解
3. 暴露早期引用(addSingletonFactory)
解决循环依赖的关键步骤(将刚实例化(但未初始化)的Bean放入三级缓存):
4. 属性填充(populateBean)
依赖注入的核心阶段:

5. Aware接口回调(invokeAwareMethods)
让Bean感知容器环境:
6. 初始化前处理(applyBeanPostProcessorsBeforeInitialization)
执行@PostConstruct
等初始化前回调:
典型处理器:
CommonAnnotationBeanPostProcessor
:执行@PostConstruct
方法ApplicationContextAwareProcessor
:处理ApplicationContextAware
等接口
7. 执行初始化(invokeInitMethods)
调用初始化方法:
8. 初始化后处理(applyBeanPostProcessorsAfterInitialization)
AOP代理生成的关键阶段:


AOP代理创建流程:

9. 注册销毁方法(registerDisposableBean)
为Bean注册销毁回调:

四、循环依赖解决机制
Spring使用三级缓存解决单例Bean的循环依赖:
解决流程:
1. 为什么需要三级缓存?
这是Spring设计中最精妙的部分:
- 三级缓存存储的不是Bean实例,而是ObjectFactory
- 在获取早期引用时才调用工厂创建对象
- 允许后处理器介入(如创建AOP代理)
2. 二级缓存的作用
二级缓存主要作为临时存储:
- 避免多次调用工厂方法
- 保证单例Bean在创建过程中全局唯一
五、性能优化策略
Bean初始化耗时分析
阶段 | 耗时占比 | 优化方向 |
---|---|---|
类加载 | 10-20% | 减少依赖 |
实例化 | 15-25% | 简化构造 |
依赖注入 | 30-50% | 减少依赖 |
AOP代理 | 10-20% | 精简切面 |
初始化回调 | 5-15% | 优化逻辑 |
实战优化技巧
- 精简Bean依赖图
- 使用构造器注入
- 延迟初始化策略
- 优化AOP切面
六、常见问题排查
1. Bean创建失败场景
案例1:循环依赖无法解决
java
@Service
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
@Service
public class ServiceB {
@Autowired
public ServiceB(ServiceA serviceA) { ... } // 构造器注入导致问题
}
解决方案:改用Setter注入或字段注入
案例2:初始化方法异常
java
@Service
public class ConfigService {
@PostConstruct
public void init() {
throw new RuntimeException("DB连接失败");
}
}
解决方案:添加异常处理机制
2. 性能问题定位
使用Spring Boot Actuator监控Bean初始化时间:
yaml
management:
endpoints:
web:
exposure:
include: beans
endpoint:
beans:
enabled: true
访问/actuator/beans
获取Bean初始化耗时数据:
json
{
"beans": [
{
"bean": "userService",
"startupTime": 125 // 初始化耗时(ms)
},
{
"bean": "orderService",
"startupTime": 68
}
]
}
七、最佳实践总结
设计原则
- 保持Bean轻量级:避免在Bean中包含过多业务逻辑
- 最小化依赖:减少Bean之间的依赖关系
- 优先使用构造器注入:提高代码可测试性和可维护性
性能优化
- 合理使用延迟加载:对非关键路径的Bean使用
@Lazy
- 精简AOP切面:精确指定切入点表达式
- 优化初始化方法:避免在
@PostConstruct
中执行耗时操作
finishBeanFactoryInitialization
是Spring IOC容器中最复杂、最核心 的阶段,它完成了从Bean定义到可用对象的转变过程。理解finishBeanFactoryInitialization
阶段的内部机制,是掌握Spring框架精髓的关键。通过合理设计和优化,可以显著提升应用启动速度和运行效率。
End!