Spring 启动流程深度解析

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() 方法源码骨架

java 复制代码
@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():准备刷新

java 复制代码
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

java 复制代码
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

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

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

4.3 prepareBeanFactory(beanFactory):配置 BeanFactory

java 复制代码
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

java 复制代码
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

java 复制代码
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

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

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

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

java 复制代码
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():初始化事件广播器

java 复制代码
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():注册监听器

java 复制代码
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 初始化

java 复制代码
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():完成刷新

java 复制代码
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 应用 #mermaid-svg-nb1PR9NylnK3QAqT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nb1PR9NylnK3QAqT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nb1PR9NylnK3QAqT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nb1PR9NylnK3QAqT .error-icon{fill:#552222;}#mermaid-svg-nb1PR9NylnK3QAqT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nb1PR9NylnK3QAqT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nb1PR9NylnK3QAqT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nb1PR9NylnK3QAqT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nb1PR9NylnK3QAqT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nb1PR9NylnK3QAqT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nb1PR9NylnK3QAqT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nb1PR9NylnK3QAqT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nb1PR9NylnK3QAqT .marker.cross{stroke:#333333;}#mermaid-svg-nb1PR9NylnK3QAqT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nb1PR9NylnK3QAqT p{margin:0;}#mermaid-svg-nb1PR9NylnK3QAqT .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nb1PR9NylnK3QAqT text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-nb1PR9NylnK3QAqT .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nb1PR9NylnK3QAqT .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-nb1PR9NylnK3QAqT .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-nb1PR9NylnK3QAqT .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-nb1PR9NylnK3QAqT #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-nb1PR9NylnK3QAqT .sequenceNumber{fill:white;}#mermaid-svg-nb1PR9NylnK3QAqT #sequencenumber{fill:#333;}#mermaid-svg-nb1PR9NylnK3QAqT #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-nb1PR9NylnK3QAqT .messageText{fill:#333;stroke:none;}#mermaid-svg-nb1PR9NylnK3QAqT .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nb1PR9NylnK3QAqT .labelText,#mermaid-svg-nb1PR9NylnK3QAqT .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-nb1PR9NylnK3QAqT .loopText,#mermaid-svg-nb1PR9NylnK3QAqT .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-nb1PR9NylnK3QAqT .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nb1PR9NylnK3QAqT .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-nb1PR9NylnK3QAqT .noteText,#mermaid-svg-nb1PR9NylnK3QAqT .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-nb1PR9NylnK3QAqT .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nb1PR9NylnK3QAqT .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nb1PR9NylnK3QAqT .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nb1PR9NylnK3QAqT .actorPopupMenu{position:absolute;}#mermaid-svg-nb1PR9NylnK3QAqT .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-nb1PR9NylnK3QAqT .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nb1PR9NylnK3QAqT .actor-man circle,#mermaid-svg-nb1PR9NylnK3QAqT line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-nb1PR9NylnK3QAqT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 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)提供了明确的集成点。