概述

本文深入探讨 Spring IoC 容器的初始化流程,通过断点调试分析 Bean 的实例化时机。

调试测试

文章通过断点调试解答核心问题:Bean 的创建是在容器初始化时还是 getBean 时?

断点1:getBean

getBean 行设置断点,启动 Debug 模式观察发现:在未配置延迟加载的情况下,Bean 的创建在容器初始化时就已完成。

断点2:afterPropertiesSet

WzkBeanafterPropertiesSet 函数设断点,可看到构造函数调用时机位于 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 初始化过程

  1. @PostConstruct 标注的方法执行
  2. InitializingBean.afterPropertiesSet() 调用
  3. 自定义初始化方法 调用
  4. BeanPostProcessor.postProcessBeforeInitialization() 执行
  5. BeanPostProcessor.postProcessAfterInitialization() 执行

总结

Spring IoC 容器通过 AbstractApplicationContext.refresh() 方法完成初始化,核心在于 finishBeanFactoryInitialization(beanFactory) 阶段完成所有非懒加载单例 Bean 的实例化和初始化。