概述
本文深入探讨 Spring IoC 容器的初始化流程,通过断点调试分析 Bean 的实例化时机。
调试测试
文章通过断点调试解答核心问题:Bean 的创建是在容器初始化时还是 getBean 时?
断点1:getBean
在 getBean 行设置断点,启动 Debug 模式观察发现:在未配置延迟加载的情况下,Bean 的创建在容器初始化时就已完成。
断点2:afterPropertiesSet
在 WzkBean 的 afterPropertiesSet 函数设断点,可看到构造函数调用时机位于 AbstractApplicationContext 类的 refresh 方法的 finishBeanFactoryInitialization 阶段。
断点3:BeanFactoryPostProcessor
- 初始化位置:
AbstractApplicationContext.refresh()→invokeBeanFactoryPostProcessor(beanFactory) - 调用位置: 同上
断点4:BeanPostProcessor
- 初始化:
AbstractApplicationContext.refresh()→registerBeanPostProcessor(beanFactory) - postProcessBeforeInitialization:
finishBeanFactoryInitialization(beanFactory)阶段 - postProcessAfterInitialization: 同上
IoC 容器初始化主流程
AbstractApplicationContext#refresh() 方法是核心:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 刷新前预处理
prepareRefresh();
// 获取新BeanFactory实例,加载BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 为BeanFactory设置基础属性
prepareBeanFactory(beanFactory);
try {
// BeanFactory后置处理
postProcessBeanFactory(beanFactory);
// 调用BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 初始化MessageSource
initMessageSource();
// 初始化事件广播器
initApplicationEventMulticaster();
// 子类刷新逻辑
onRefresh();
// 注册监听器
registerListeners();
// 初始化所有非懒加载单例Bean
finishBeanFactoryInitialization(beanFactory);
// 完成容器刷新
finishRefresh();
}
}
}
IoC 容器初始化关键步骤
| 步骤 | 说明 |
|---|---|
| 1 | 创建容器实例 |
| 2 | 加载 Bean 定义(XML/注解/Java配置类) |
| 3 | 注册 Bean 定义 |
| 4 | 处理 Bean 依赖注入 |
| 5 | 实例化 Bean |
| 6 | 初始化 Bean(@PostConstruct、InitializingBean、自定义init-method) |
| 7 | 注册 Bean 后处理器 |
| 8 | 激活 Bean 生命周期 |
| 9 | 完成容器初始化 |
Bean 初始化过程
- @PostConstruct 标注的方法执行
- InitializingBean.afterPropertiesSet() 调用
- 自定义初始化方法 调用
- BeanPostProcessor.postProcessBeforeInitialization() 执行
- BeanPostProcessor.postProcessAfterInitialization() 执行
总结
Spring IoC 容器通过 AbstractApplicationContext.refresh() 方法完成初始化,核心在于 finishBeanFactoryInitialization(beanFactory) 阶段完成所有非懒加载单例 Bean 的实例化和初始化。