Spring 启动流程深度解析:AbstractApplicationContext.refresh()

一、背景

Spring 框架的核心能力之一就是 IoC 容器,它负责管理应用中的 Bean 定义、创建、依赖注入以及生命周期回调。容器的启动过程将配置元数据(XML、注解、Java Config 等)转化为一个可用的 ApplicationContext 实例,这个过程高度浓缩在 AbstractApplicationContext.refresh() 方法中。理解 refresh() 的每一步,是深入掌握 Spring 原理、排查启动问题的基础。

二、refresh() 整体概览

AbstractApplicationContext.refresh() 是 Spring 应用上下文启动的核心,它定义了容器初始化的统一模板,内部按照固定顺序调用十多个子方法,每个方法负责一个子任务。方法本身使用 synchronized 保证并发安全,并通过 startupShutdownMonitor 锁避免重复刷新。

整个流程可以概括为以下几个阶段:

  1. 准备阶段:记录启动时间、初始化占位符属性源、验证必要属性。
  2. BeanFactory 创建与配置阶段:创建内部的 DefaultListableBeanFactory,加载 Bean 定义。
  3. BeanFactory 后处理阶段:执行 BeanFactoryPostProcessor,允许修改 Bean 定义。
  4. Bean 后处理器注册阶段:注册 BeanPostProcessor,为后续 Bean 初始化做准备。
  5. 国际化与事件广播器初始化:初始化 MessageSourceApplicationEventMulticaster
  6. 其他特定上下文的刷新:留给子类的扩展点,如 Spring Boot 中会启动内嵌 Web 服务器。
  7. 事件监听器注册阶段:注册 ApplicationListener 并发布早期事件。
  8. Bean 实例化阶段:完成所有非懒加载单例 Bean 的初始化。
  9. 完成刷新:发布 ContextRefreshedEvent,容器启动完毕。

三、refresh() 方法源码骨架

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 准备刷新
        prepareRefresh();
        // 2. 创建并配置 BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 3. 准备 BeanFactory
        prepareBeanFactory(beanFactory);
        try {
            // 4. BeanFactory 后处理(留给子类覆盖)
            postProcessBeanFactory(beanFactory);
            // 5. 执行 BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);
            // 6. 注册 BeanPostProcessor
            registerBeanPostProcessors(beanFactory);
            // 7. 初始化 MessageSource
            initMessageSource();
            // 8. 初始化事件广播器
            initApplicationEventMulticaster();
            // 9. 留给子类的刷新回调
            onRefresh();
            // 10. 注册事件监听器
            registerListeners();
            // 11. 完成剩余单例 Bean 的初始化
            finishBeanFactoryInitialization(beanFactory);
            // 12. 完成刷新
            finishRefresh();
        } catch (BeansException ex) {
            // 销毁已创建的 Bean
            destroyBeans();
            // 重置激活状态
            cancelRefresh(ex);
            throw ex;
        } finally {
            // 重置公共缓存
            resetCommonCaches();
        }
    }
}

下面逐步拆解每个方法的具体职责。

四、各步骤详解

4.1 prepareRefresh():准备刷新

protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    // 初始化属性源(留给子类扩展,如 Spring Boot 加载 application.properties)
    initPropertySources();
    // 校验必要属性
    getEnvironment().validateRequiredProperties();
    // 存储早期应用监听器
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    } else {
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }
    // 初始化早期事件集合(用于后续分发)
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

此步骤完成启动时间记录、状态标记,以及环境属性的准备和校验。initPropertySources() 是一个空模板,在 Spring Boot 的 ServletWebServerApplicationContext 中会初始化 servlet 相关的属性源。

4.2 obtainFreshBeanFactory():获取 BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

refreshBeanFactory() 是抽象方法,由具体实现类负责。以 AbstractRefreshableApplicationContext 为例,它会创建一个新的 DefaultListableBeanFactory,并调用 loadBeanDefinitions(beanFactory) 加载所有 Bean 定义(从 XML、注解等资源)。

最终返回的 ConfigurableListableBeanFactory 是 Spring 容器最底层的 Bean 注册表,后续所有 Bean 管理都通过它。

4.3 prepareBeanFactory(beanFactory):配置 BeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // 设置表达式解析器(SpEL)
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    // 添加属性编辑器注册器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    // 添加 ApplicationContextAwareProcessor,处理各种 Aware 接口回调
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    // 忽略以下 Aware 接口的自动装配(因为它们会通过 setter 手工注入)
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    // 注册一些可解析依赖
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    // 添加 ApplicationListenerDetector,收集实现了 ApplicationListener 的 Bean
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    // 检测并注入 LoadTimeWeaver(如果存在)
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    // 注册默认环境 Bean
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

这一步对 BeanFactory 进行了标准配置,包括类加载器、SpEL 解析器、属性编辑器、Aware 回调处理器等,使得 Bean 可以感知到容器相关组件。

4.4 postProcessBeanFactory(beanFactory):BeanFactory 后处理(子类扩展点)

这是一个模板方法,在 AbstractApplicationContext 中为空,允许子类在 BeanFactory 标准配置完成后、Bean 定义加载后,进行额外的定制。例如,在 Spring Boot 的 AnnotationConfigServletWebServerApplicationContext 中,会在这里扫描指定包并注册相关 Bean。

4.5 invokeBeanFactoryPostProcessors(beanFactory):调用 BeanFactoryPostProcessor

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    // ...
}

这里会执行所有注册的 BeanFactoryPostProcessor(包括通过 XML 或注解声明的,以及编程式添加的)。分两个阶段:

  • 首先执行 BeanDefinitionRegistryPostProcessor(它是 BeanFactoryPostProcessor 的子接口),允许向容器中注册新的 Bean 定义。例如 ConfigurationClassPostProcessor 就是实现此接口,负责解析 @Configuration 类,处理 @Bean@ComponentScan 等注解,生成对应的 Bean 定义。
  • 再执行普通的 BeanFactoryPostProcessor,可以对已加载的 Bean 定义进行修改。

此步骤完成后,所有 Bean 的定义元数据都已就绪。

4.6 registerBeanPostProcessors(beanFactory):注册 BeanPostProcessor

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

BeanPostProcessor 会在每个 Bean 初始化前后执行回调,但不影响 Bean 定义。这一步仅仅是将这些处理器本身注册到容器中,并不执行。注册时按照优先级(PriorityOrdered > Ordered > 普通)排序后加入内部列表。

常见的 BeanPostProcessorAutowiredAnnotationBeanPostProcessor(处理 @Autowired 注入)、CommonAnnotationBeanPostProcessor(处理 @PostConstruct 等)都在这里被注册。

4.7 initMessageSource():初始化国际化资源

protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        // 设置父级 MessageSource(如果有)
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            ((HierarchicalMessageSource) this.messageSource).setParentMessageSource(
                    getInternalParentMessageSource());
        }
    } else {
        // 没有用户定义的,用默认的空实现
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    }
}

如果用户没有定义 messageSource Bean,Spring 会注册一个默认的 DelegatingMessageSource,避免后续使用时出现 NPE。

4.8 initApplicationEventMulticaster():初始化事件广播器

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster = beanFactory.getBean(
                APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    } else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
}

默认使用 SimpleApplicationEventMulticaster,它内部用 Executor 可以支持异步事件分发(否则在发布事件线程同步执行)。

4.9 onRefresh():子类刷新的特殊处理

又一个模板方法,AbstractApplicationContext 中为空。Spring Boot 的 Web 容器在这里启动内嵌的 Tomcat/Jetty/Undertow,即 createWebServer() 被调用,从而完成 HTTP 端口的监听。

4.10 registerListeners():注册监听器

protected void registerListeners() {
    // 先注册静态指定的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    // 从容器中获取所有 ApplicationListener Bean 并注册
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    // 发布早期事件(在 multicaster 初始化前产生的事件)
    Set<ApplicationEvent> earlyEvents = getEarlyApplicationEvents();
    if (earlyEvents != null) {
        for (ApplicationEvent earlyEvent : earlyEvents) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

这一步之后,事件广播器开始运作。earlyApplicationEvents 中暂存的事件会被发布出去。

4.11 finishBeanFactoryInitialization(beanFactory):完成 BeanFactory 初始化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化 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));
    }
    // 添加默认的嵌入值解析器,解析 @Value 中的 ${...}
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }
    // 提前初始化 LoadTimeWeaverAware Bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    // 禁用临时 ClassLoader
    beanFactory.setTempClassLoader(null);
    // 冻结配置,不让再修改
    beanFactory.freezeConfiguration();
    // 实例化所有非懒加载的单例 Bean
    beanFactory.preInstantiateSingletons();
}

这一步是容器启动最耗时的部分。preInstantiateSingletons() 会遍历所有非懒加载的单例 Bean 定义,依次调用 getBean() 完成 Bean 的创建和依赖注入。具体实例化流程包括:

  1. 通过 createBeanInstance 创建 Bean 实例(反射或 CGLIB)。
  2. 填充属性(populateBean),处理 @Autowired 等注解注入。
  3. 调用 initializeBean,执行 BeanPostProcessor 的前置处理、InitializingBean.afterPropertiesSet()init-method

所有单例 Bean 初始化完成后,它们会被放入 singletonObjects 一级缓存中,容器进入就绪状态。

4.12 finishRefresh():完成刷新

protected void finishRefresh() {
    // 清除资源缓存
    clearResourceCaches();
    // 初始化 LifecycleProcessor 并调用 onRefresh
    initLifecycleProcessor();
    getLifecycleProcessor().onRefresh();
    // 发布 ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));
    // 注册到 LiveBeansView(JMX)
    LiveBeansView.registerApplicationContext(this);
}

LifecycleProcessor.onRefresh() 会启动所有实现了 Lifecycle 接口且 autoStartup=true 的 Bean(如后台线程池)。最后发布 ContextRefreshedEvent,标志着容器完全启动。

五、全流程时序图

单例Bean实例 SimpleApplicationEventMulticaster BeanPostProcessor BeanDefinitionRegistryPostProcessor DefaultListableBeanFactory AbstractApplicationContext 应用 单例Bean实例 SimpleApplicationEventMulticaster BeanPostProcessor BeanDefinitionRegistryPostProcessor DefaultListableBeanFactory AbstractApplicationContext 应用 refresh() prepareRefresh() (记录时间、初始化环境) obtainFreshBeanFactory() (创建BF、加载Bean定义) prepareBeanFactory(bf) (配置标准属性) postProcessBeanFactory(bf) (子类扩展) invokeBeanFactoryPostProcessors(bf) 解析配置、注册额外Bean定义 registerBeanPostProcessors(bf) 注册BeanPostProcessor实例 initMessageSource() initApplicationEventMulticaster() onRefresh() (子类可启动web服务器) registerListeners() (注册监听器) finishBeanFactoryInitialization(bf) preInstantiateSingletons() (实例化所有单例Bean) 创建实例、填充属性、init-method 初始化完成 finishRefresh() publishEvent(ContextRefreshedEvent) 容器启动完成

六、与 Dubbo 服务发布/消费的关联

Dubbo 与 Spring 容器紧密集成,其服务发布与消费正是借助了 Spring 启动流程中的扩展点。

  • 服务发布入口:Dubbo 的 DubboBootstrapApplicationListener 监听 ApplicationContextEvent,在 Spring 容器 finishRefresh() 发布 ContextRefreshedEvent 后触发。随后调用 DubboBootstrap.start(),执行 ServiceConfig.export(),完成服务暴露。
  • 服务消费入口:对于 @DubboReference 注解,Dubbo 通过 ReferenceAnnotationBeanPostProcessor(一个 BeanPostProcessor)在 Spring 的 finishBeanFactoryInitialization 阶段进行依赖注入。它会在 Bean 属性填充时,识别带有 @DubboReference 的字段,调用 ReferenceConfig.get() 生成远程服务代理并注入。

理解 Spring 的 refresh() 流程,就能清楚地看到 Dubbo 在哪个时间节点介入,服务暴露为何发生在容器启动的最后阶段,以及消费端代理何时被创建并注入。

七、总结

步骤 关键方法 核心作用
1 prepareRefresh 准备环境、记录时间、校验属性
2 obtainFreshBeanFactory 创建 BeanFactory、加载 Bean 定义
3 prepareBeanFactory 配置 BeanFactory 标准特性
4 postProcessBeanFactory 子类自定义 BeanFactory 后处理
5 invokeBeanFactoryPostProcessors 执行 BeanFactoryPostProcessor,修改 Bean 定义
6 registerBeanPostProcessors 注册 BeanPostProcessor
7 initMessageSource 初始化国际化资源
8 initApplicationEventMulticaster 初始化事件广播器
9 onRefresh 子类特殊启动逻辑(如 Web 服务器)
10 registerListeners 注册监听器、发布早期事件
11 finishBeanFactoryInitialization 实例化所有单例非懒加载 Bean
12 finishRefresh 启动 Lifecycle,发布 ContextRefreshedEvent

Spring 的 refresh() 方法提供了一个高度可扩展的容器启动模板,开发者可以在各个步骤中插入自定义逻辑,同时也为其他框架(如 Dubbo)提供了明确的集成点。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐