乐于分享
好东西不私藏

Spring Boot 源码解析(四):IoC 容器初始化深度剖析

Spring Boot 源码解析(四):IoC 容器初始化深度剖析

大家好,老 J。

前三期我们讲了启动流程、@SpringBootApplication 注解、自动配置原理。这一期进入 Spring 最核心、最复杂、面试最高频的部分——IoC 容器的初始化过程

说白了,就是 refresh() 方法里面的 12 个步骤。

面试官问“Spring 启动过程”,如果你能把 refresh() 这 12 步讲清楚,基本就过关了。

一、refresh() 方法概览

refresh() 是 AbstractApplicationContext 中的核心方法,定义了 Spring 容器的初始化流程。

// AbstractApplicationContext.java@Overridepublicvoidrefresh()throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1. 刷新前的准备工作        prepareRefresh();// 2. 获取 BeanFactoryConfigurableListableBeanFactorybeanFactory= obtainFreshBeanFactory();// 3. BeanFactory 的准备工作(设置类加载器、后置处理器等)        prepareBeanFactory(beanFactory);// 4. 子类处理(Web 容器会在这里做扩展)        postProcessBeanFactory(beanFactory);// 5. 调用 BeanFactory 后置处理器        invokeBeanFactoryPostProcessors(beanFactory);// 6. 注册 Bean 后置处理器        registerBeanPostProcessors(beanFactory);// 7. 初始化消息源(国际化)        initMessageSource();// 8. 初始化事件广播器        initApplicationEventMulticaster();// 9. 子类初始化(Web 容器在这里启动 Tomcat)        onRefresh();// 10. 注册监听器        registerListeners();// 11. 实例化所有非懒加载的单例 Bean(核心!)        finishBeanFactoryInitialization(beanFactory);// 12. 完成刷新,发布 ContextRefreshedEvent 事件        finishRefresh();    }}

二、12 步逐层拆解

第 1 步:prepareRefresh()——刷新前的准备工作

protectedvoidprepareRefresh() {// 设置启动时间this.startupDate = System.currentTimeMillis();// 设置容器为活动状态this.closed.set(false);this.active.set(true);// 初始化属性源(占位方法,子类可覆盖)    initPropertySources();// 校验必须存在的属性    getEnvironment().validateRequiredProperties();// 初始化早期事件监听器集合this.earlyApplicationEvents = newLinkedHashSet<>();}

作用: 设置容器状态、初始化环境、验证属性。


第 2 步:obtainFreshBeanFactory()——获取 BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新 BeanFactory(子类实现)    refreshBeanFactory();// 返回 BeanFactoryreturn getBeanFactory();}

在 GenericApplicationContext 中的实现:

@OverrideprotectedfinalvoidrefreshBeanFactory()throws IllegalStateException {// 如果已有 BeanFactory,先销毁if (this.refreshed) {thrownewIllegalStateException("...");    }// 设置序列化 IDthis.beanFactory.setSerializationId(getId());this.refreshed = true;}

作用: 获取或创建 BeanFactoryDefaultListableBeanFactory)。


第 3 步:prepareBeanFactory()——准备 BeanFactory

protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 设置类加载器    beanFactory.setBeanClassLoader(getClassLoader());// 设置表达式解析器(支持 SpEL)    beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(...));// 设置属性编辑器注册器    beanFactory.addPropertyEditorRegistrar(newResourceEditorRegistrar(...));// 添加 BeanPostProcessor(ApplicationContextAware 处理)    beanFactory.addBeanPostProcessor(newApplicationContextAwareProcessor(this));// 忽略某些接口的自动装配    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// 注册特殊类型 Bean 的自动装配    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);    beanFactory.registerResolvableDependency(ResourceLoader.class, this);    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);    beanFactory.registerResolvableDependency(ApplicationContext.class, this);// 注册早期 BeanPostProcessor    beanFactory.addBeanPostProcessor(newApplicationListenerDetector(this));// 检测 LoadTimeWeaverif (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {        beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));        beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(...));    }// 注册环境相关单例 Beanif (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());    }// ... 注册 systemProperties、systemEnvironment 等}

作用: 设置 BeanFactory 的基础设施,包括类加载器、表达式解析器、特殊类型注入等。


第 4 步:postProcessBeanFactory()——子类扩展

protectedvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 空方法,子类覆盖}

Web 容器的实现(AnnotationConfigServletWebServerApplicationContext):

@OverrideprotectedvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 添加 Web 相关的 BeanPostProcessor    beanFactory.addBeanPostProcessor(newWebApplicationContextServletContextAwareProcessor(this));    beanFactory.ignoreDependencyInterface(ServletContextAware.class);// 注册 Web 相关单例if (this.servletContext != null) {        beanFactory.registerResolvableDependency(ServletContext.class, this.servletContext);    }}

第 5 步:invokeBeanFactoryPostProcessors()——执行 BeanFactory 后置处理器

这是非常重要的一步,负责执行所有 BeanFactoryPostProcessor

protectedvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 委托给 PostProcessorRegistrationDelegate 执行    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// 检测 LoadTimeWeaverif (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {        beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));        beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(...));    }}

核心执行逻辑:

BeanFactoryPostProcessor 执行顺序:1. 先执行 BeanDefinitionRegistryPostProcessor(可以注册 Bean 定义)   ├── 优先执行实现了 PriorityOrdered 接口的   ├── 然后执行实现了 Ordered 接口的   └── 最后执行其他的2. 再执行普通的 BeanFactoryPostProcessor   ├── 优先执行 PriorityOrdered   ├── 然后执行 Ordered   └── 最后执行其他的

典型应用:@ComponentScan@Import@Bean 的解析都是在这一步完成的。


第 6 步:registerBeanPostProcessors()——注册 Bean 后置处理器

protectedvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}

作用: 注册 BeanPostProcessor,这些处理器会在 Bean 实例化前后执行。

执行顺序:

  1. 1. 先注册 PriorityOrdered 类型的
  2. 2. 再注册 Ordered 类型的
  3. 3. 最后注册普通的
  4. 4. 注册 MergedBeanDefinitionPostProcessor(特殊处理)

常见 BeanPostProcessor:

  • • AutowiredAnnotationBeanPostProcessor:处理 @Autowired 注入
  • • CommonAnnotationBeanPostProcessor:处理 @Resource@PostConstruct 等
  • • ApplicationContextAwareProcessor:处理各种 *Aware 接口

第 7 步:initMessageSource()——初始化国际化

protectedvoidinitMessageSource() {ConfigurableListableBeanFactorybeanFactory= getBeanFactory();// 检查是否有自定义的 MessageSourceif (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// ...    } else {// 没有则创建一个空的 DelegatingMessageSourceDelegatingMessageSourcedms=newDelegatingMessageSource();        dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);    }}

第 8 步:initApplicationEventMulticaster()——初始化事件广播器

protectedvoidinitApplicationEventMulticaster() {ConfigurableListableBeanFactorybeanFactory= getBeanFactory();// 检查是否有自定义的 ApplicationEventMulticasterif (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster = beanFactory.getBean(            APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);    } else {// 默认使用 SimpleApplicationEventMulticasterthis.applicationEventMulticaster = newSimpleApplicationEventMulticaster(beanFactory);        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);    }}

作用: 初始化事件广播器,用于 Spring 的事件机制。


第 9 步:onRefresh()——子类初始化(Web 容器启动点)

protectedvoidonRefresh()throws BeansException {// 空方法,子类覆盖}

Web 容器的实现(重要!Tomcat 在这里启动):

// ServletWebServerApplicationContext.onRefresh()@OverrideprotectedvoidonRefresh() {super.onRefresh();try {        createWebServer();  // 创建并启动 Tomcat    } catch (Throwable ex) {thrownewApplicationContextException("Unable to start web server", ex);    }}privatevoidcreateWebServer() {WebServerFactoryfactory= getWebServerFactory();this.webServer = factory.getWebServer(getSelfInitializer());// Tomcat 在这里启动}

第 10 步:registerListeners()——注册监听器

protectedvoidregisterListeners() {// 注册静态指定的监听器for (ApplicationListener<?> listener : getApplicationListeners()) {        getApplicationEventMulticaster().addApplicationListener(listener);    }// 注册容器中所有 ApplicationListener 类型的 Bean    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, truefalse);for (String listenerBeanName : listenerBeanNames) {        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);    }// 处理早期事件(refresh 之前发布的事件)    Set<ApplicationEvent> earlyEvents = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEvents != null) {for (ApplicationEvent earlyEvent : earlyEvents) {            getApplicationEventMulticaster().multicastEvent(earlyEvent);        }    }}

第 11 步:finishBeanFactoryInitialization()——实例化单例 Bean(最核心!)

这一步是整个 refresh() 中最重要的步骤,负责实例化所有非懒加载的单例 Bean。

protectedvoidfinishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 1. 初始化 ConversionService(类型转换服务)if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {        beanFactory.setConversionService(            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));    }// 2. 注册默认的嵌入值解析器if (!beanFactory.hasEmbeddedValueResolver()) {        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));    }// 3. 初始化 LoadTimeWeaver    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, falsefalse);for (String weaverAwareName : weaverAwareNames) {        getBean(weaverAwareName);    }// 4. 停止使用临时类加载器    beanFactory.setTempClassLoader(null);// 5. 冻结配置(所有 Bean 定义不再允许修改)    beanFactory.freezeConfiguration();// 6. 实例化所有非懒加载的单例 Bean(核心!)    beanFactory.preInstantiateSingletons();}

preInstantiateSingletons() 核心逻辑:

// DefaultListableBeanFactory.java@OverridepublicvoidpreInstantiateSingletons()throws BeansException {// 获取所有 Bean 名称    List<String> beanNames = newArrayList<>(this.beanDefinitionNames);for (String beanName : beanNames) {RootBeanDefinitionbd= getMergedLocalBeanDefinition(beanName);// 跳过抽象类、懒加载、多例if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// 判断是否是 FactoryBeanif (isFactoryBean(beanName)) {// FactoryBean 的处理                FactoryBean<?> factory = getBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class);if (factory.isEagerInit()) {                    getBean(beanName);                }            } else {// 普通 Bean,调用 getBean() 实例化                getBean(beanName);            }        }    }// 触发 SmartInitializingSingleton 回调for (String beanName : beanNames) {ObjectsingletonInstance= getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {            ((SmartInitializingSingleton) singletonInstance).afterSingletonsInstantiated();        }    }}

getBean() 的调用链:

getBean(beanName)    ↓doGetBean(beanName, ...)    ↓getSingleton(beanName)  // 尝试从缓存获取    ↓ (如果没有)createBean(beanName, ...)    ↓doCreateBean(beanName, ...)    ↓createBeanInstance()      // 实例化(调用构造器)    ↓populateBean()            // 属性填充(@Autowired 在这里完成)    ↓initializeBean()          // 初始化(@PostConstruct、init-method、AOP)

第 12 步:finishRefresh()——完成刷新

protectedvoidfinishRefresh() {// 1. 清除 ResourceLoader 缓存    clearResourceCaches();// 2. 初始化生命周期处理器    initLifecycleProcessor();// 3. 调用 LifecycleProcessor 的 onRefresh 方法    getLifecycleProcessor().onRefresh();// 4. 发布 ContextRefreshedEvent 事件    publishEvent(newContextRefreshedEvent(this));// 5. 注册 MBean(JMX)    LiveBeansView.registerApplicationContext(this);}

三、一张图总结 refresh() 12 步

                    ┌─────────────────────────────────┐                    │         refresh() 启动           │                    └────────────────┬────────────────┘                                     │                    ┌────────────────▼────────────────┐                    │ 1. prepareRefresh               │ 准备刷新                    └────────────────┬────────────────┘                                     │                    ┌────────────────▼────────────────┐                    │ 2. obtainFreshBeanFactory       │ 获取 BeanFactory                    └────────────────┬────────────────┘                                     │                    ┌────────────────▼────────────────┐                    │ 3. prepareBeanFactory           │ 准备 BeanFactory                    └────────────────┬────────────────┘                                     │                    ┌────────────────▼────────────────┐                    │ 4. postProcessBeanFactory       │ 子类扩展                    └────────────────┬────────────────┘                                     │                    ┌────────────────▼────────────────┐                    │ 5. invokeBeanFactoryPostProcessors│ 执行 BeanFactory 后置处理器                    │    (解析 @ComponentScan、@Bean)  │                    └────────────────┬────────────────┘                                     │                    ┌────────────────▼────────────────┐                    │ 6. registerBeanPostProcessors   │ 注册 Bean 后置处理器                    └────────────────┬────────────────┘                                     │            ┌────────┬────────┬───────┴───────┬────────┬────────┐            ▼        ▼        ▼               ▼        ▼        ▼        7.init     8.init    9.onRefresh    10.reg   11.实例化  12.finish        Message    Event     (Tomcat启动)    Listener   Bean    Refresh        Source     Broadcaster

四、面试回答模板

问:Spring 容器的启动过程是怎样的?

Spring 容器的启动核心是 refresh() 方法,一共 12 个步骤:

  1. 1. prepareRefresh:设置容器状态,初始化环境变量
  2. 2. obtainFreshBeanFactory:获取或创建 BeanFactory
  3. 3. prepareBeanFactory:设置类加载器、表达式解析器等
  4. 4. postProcessBeanFactory:子类扩展,Web 容器会在这里添加扩展
  5. 5. invokeBeanFactoryPostProcessors:执行 BeanFactory 后置处理器,@ComponentScan@Bean 的解析在这里完成
  6. 6. registerBeanPostProcessors:注册 Bean 后置处理器,如 @Autowired 的处理
  1. 7. initMessageSource:初始化国际化
  2. 8. initApplicationEventMulticaster:初始化事件广播器
  3. 9. onRefresh:子类初始化,Web 容器在这里启动 Tomcat
  4. 10. registerListeners:注册事件监听器
  5. 11. finishBeanFactoryInitialization:实例化所有非懒加载的单例 Bean,这是最核心的一步
  6. 12. finishRefresh:完成刷新,发布 ContextRefreshedEvent

其中,第 5 步负责 Bean 定义的解析,第 6 步注册处理器,第 11 步真正实例化 Bean。

五、下期预告

Spring Boot 源码解析(五):Bean 的实例化与循环依赖解决

  • • getBean() 的完整流程
  • • 三级缓存如何解决循环依赖
  • • @Autowired 的工作原理
  • • 面试高频题:为什么 Spring 能解决循环依赖?

六、互动时间

refresh() 12 步,最让你头疼的是哪一步?

  • • 循环依赖的原理?
  • • AOP 代理的创建时机?
  • • FactoryBean 的处理?

评论区聊聊,老 J 给你解答。


我是老 J,下期见。