Spring 源码解读:从启动流程看 IoC 容器的核心实现

142 阅读16分钟

序言

Spring 是 Java 生态中最流行的轻量级框架之一,其核心是 IoC(控制反转)容器 和 AOP(面向切面编程)。理解 Spring 的源码不仅有助于我们更好地掌握其内部机制,还能提升我们在实际开发中对配置、性能优化以及问题排查的能力。

本文将以 Spring Framework 6.x 为基础,重点解析 Spring 容器的启动流程,深入探讨 ApplicationContext、BeanFactory、BeanDefinition 等核心组件的实现原理。

1. Spring 启动流程概述

Spring 容器的启动过程主要分为以下几个阶段:

  • 加载配置
  • 创建 BeanFactory
  • 注册 BeanDefinition
  • 刷新上下文(refresh)
  • 实例化单例 Bean

以最常见的 ClassPathXmlApplicationContext 或 AnnotationConfigApplicationContext 为例,入口代码如下:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml")

或者使用注解方式:

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

无论是 XML 配置还是注解驱动,最终都会调用 AbstractApplicationContext.refresh() 方法完成整个容器的初始化。

我们使用 Spring 的大多时候都是直接创建容器然后使用,没有思考过或者研究过 Spring 为什么可以这样。所以接下来我们就来看看这两行创建的对象过程中 Spring 究竟做了什么。

2. 核心组件与流程详解

ApplicationContext 、 BeanFactory 和 ListableBeanFactory

熟悉 Spring 框架的对这两个容器都是再熟悉不过了,就不多介绍这两个类了,这里要介绍的是 ListableBeanFactory 这个容器。下面是 Spring 源码对这个类的介绍

/** 
* 对 {@link BeanFactory} 接口的扩展,适用于能够列举所有 bean 实例的工厂实现。 
* 与按需逐个通过名称查找不同,该接口支持批量获取 bean 名称和实例。 
* 常见于预加载所有 bean 定义的容器(如基于 XML 或注解配置的工厂)。 
* 
* <p>如果此工厂是 {@link HierarchicalBeanFactory},则返回值不会考虑父工厂中的 bean, 
* 仅限当前工厂中定义的 bean。如需包含祖先工厂中的 bean,请使用工具类 {@link BeanFactoryUtils}。 
* 
* <p>本接口的方法主要作用于通过 bean 定义注册的 bean,忽略通过其他方式手动注册的 singleton(如 
* 通过 {@link org.springframework.beans.factory.config.ConfigurableBeanFactory#registerSingleton} 
* 注册的 bean),但某些方法如 {@code getBeanNamesForType} 和 {@code getBeansOfType} 
* 也会检查这些手动注册的单例。 
* 
* <p><b>注意</b>:除了 {@code getBeanDefinitionCount} 和 {@code containsBeanDefinition} 方法外, 
* 其他方法不是为频繁调用设计的,性能可能较差。 
* 
* @author Rod Johnson 
* @author Juergen Hoeller 
* @since 16 April 2001 
* @see HierarchicalBeanFactory 
* @see BeanFactoryUtils 
*/ 
public interface ListableBeanFactory extends BeanFactory {
    // 方法省略
}

三者的关系如下:

image.png 这个接口支持批量获取 bean 名称和实例,当需要遍历所有的 bean 来执行某些操作,比如初始化、验证等就会非常有用。

继续来看创建一个 ClassPathXmlApplicationContext 对象,Spring 究竟做了哪些事情。点开源码发现最后会调用下面的这段代码

/**
 * 使用给定的父上下文创建一个新的 ClassPathXmlApplicationContext,
 * 并从指定的 XML 文件中加载 bean 定义。
 *
 * @param configLocations  资源位置数组,用于定位配置文件
 * @param refresh          是否自动刷新上下文,加载所有 bean 定义并创建所有单例 bean;
 *                         如果为 false,则可以在进一步配置上下文后手动调用 refresh() 方法
 * @param parent           父应用上下文,可选参数,用于设置上下文的继承关系
 * @throws BeansException  如果上下文创建或初始化过程中发生异常
 * @see #refresh()
 */

public ClassPathXmlApplicationContext(
       String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
       throws BeansException {

    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
       refresh();
    }
}

接下来介绍一下这三个方法具体在做什么操作

super(parent)

我们知道 Spring 有一个强大的机制可以支持容器之间的继承,这种机制被称为"父子容器"(Parent-Child Container)关系。其作用是实现多个上下文之间共享一些通用配置。比如Bean对象的访问等。子容器可以访问父容器里的Bean,而父容器不能访问子容器的Bean。

一直追溯这个方法,会调用到如下逻辑:

/**
 * Create a new AbstractApplicationContext with the given parent context.
 * @param parent the parent context
 */
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
    this();
    setParent(parent);
}

this() 方法的作用是创建一个 ResourcePatternResolver对象并赋值给自身的 private final ResourcePatternResolver resourcePatternResolver;属性,这个类主要用于解析资源路径,支持通配符、递归搜索的资源查找

setParent()方法的作用设置当前应用的父级上下文

@Override
public void setParent(@Nullable ApplicationContext parent) {
    this.parent = parent;
    if (parent != null) {
       Environment parentEnvironment = parent.getEnvironment();
       if (parentEnvironment instanceof ConfigurableEnvironment configurableEnvironment) {
          getEnvironment().merge(configurableEnvironment);
       }
    }
}

这里会调用 merge() 方法来合并

public void merge(ConfigurableEnvironment parent) {
    Iterator var2 = parent.getPropertySources().iterator();

    // 合并 PropertySources(属性源)
    while(var2.hasNext()) {
        PropertySource<?> ps = (PropertySource)var2.next();
        if (!this.propertySources.contains(ps.getName())) {
            this.propertySources.addLast(ps);
        }
    }
    // 合并 ActiveProfiles(激活的 Profile)
    String[] parentActiveProfiles = parent.getActiveProfiles();
    if (!ObjectUtils.isEmpty(parentActiveProfiles)) {
        synchronized(this.activeProfiles) {
            Collections.addAll(this.activeProfiles, parentActiveProfiles);
        }
    }
    // 合并 DefaultProfiles(默认的 Profile)
    String[] parentDefaultProfiles = parent.getDefaultProfiles();
    if (!ObjectUtils.isEmpty(parentDefaultProfiles)) {
        synchronized(this.defaultProfiles) {
            this.defaultProfiles.remove("default");
            Collections.addAll(this.defaultProfiles, parentDefaultProfiles);
        }
    }
}

这段代码运行完毕后,子容器就会拥有父容器的信息。

setConfigLocations(configLocations)

这个方法的主要作用就是将传入的 configLocations 配置位置保存下来,这些位置会在后续调用 refresh() 方法时被用来加载 XML 配置文件中的 Bean 定义。

public void setConfigLocations(@Nullable String... locations) {
    if (locations != null) {
       Assert.noNullElements(locations, "Config locations must not be null");
       this.configLocations = new String[locations.length];
       for (int i = 0; i < locations.length; i++) {
          this.configLocations[i] = resolvePath(locations[i]).trim();
       }
    }
    else {
       this.configLocations = null;
    }
}

这里会对这个资源路径进行解析,大家可以打断点调试一下,主要是解析通配符,比如 ${ }这些特殊字符,解析完成后会把路径存放到 configLocations 的字符数组中。

3. refresh 方法

接下来就是最重要的 refresh 方法,几乎所有的工作量都在这个方法里面完成的。

public void refresh() throws BeansException, IllegalStateException {
    this.startupShutdownLock.lock(); // 加锁防止并发刷新
    try {
        this.startupShutdownThread = Thread.currentThread();

        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        prepareRefresh(); // 准备刷新:设置状态、校验必需属性

        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 获取 BeanFactory(解析 XML 或 注解)

        prepareBeanFactory(beanFactory); // 配置 BeanFactory 的基础功能(类加载器、表达式解析器等)

        try {
            postProcessBeanFactory(beanFactory); // 子类扩展点:可以在此修改 BeanFactory

            invokeBeanFactoryPostProcessors(beanFactory); // 执行所有 BeanFactoryPostProcessor(如 PropertyPlaceholderConfigurer)

            registerBeanPostProcessors(beanFactory); // 注册 BeanPostProcessor(如 AutowiredAnnotationBeanPostProcessor)

            initMessageSource(); // 初始化国际化消息源

            initApplicationEventMulticaster(); // 初始化应用事件广播器

            onRefresh(); // 子类扩展点:可自定义刷新逻辑(如 WebApplicationContext 创建 Web 容器)

            registerListeners(); // 注册监听器(包括 ApplicationListener bean)

            finishBeanFactoryInitialization(beanFactory); // 实例化所有非懒加载单例 Bean

            finishRefresh(); // 完成刷新:发布上下文刷新完成事件、生命周期处理器等

        } catch (异常) { ... }

        finally {
            contextRefresh.end();
        }
    }
    finally {
        this.startupShutdownThread = null;
        this.startupShutdownLock.unlock(); // 解锁
    }
}

接下来一一阅读这些方法的源码

prepareRefresh()

protected void prepareRefresh() {
    // Switch to active.
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    if (logger.isDebugEnabled()) {
       if (logger.isTraceEnabled()) {
          logger.trace("Refreshing " + this);
       }
       else {
          logger.debug("Refreshing " + getDisplayName());
       }
    }

    // Initialize any placeholder property sources in the context environment.
    initPropertySources();

    // Validate that all properties marked as required are resolvable:
    // see ConfigurablePropertyResolver#setRequiredProperties
    getEnvironment().validateRequiredProperties();

    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
       this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
       // Reset local application listeners to pre-refresh state.
       this.applicationListeners.clear();
       this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

1. 设置启动时间 & 激活状态

this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
  • startupDate:记录容器的启动时间。
  • closed.set(false) :表示上下文未关闭。
  • active.set(true) :标记上下文处于激活状态(正在运行中)。

📌 这些状态信息在容器生命周期管理和日志输出中很有用。


2. 打印日志

if (logger.isDebugEnabled()) {
    if (logger.isTraceEnabled()) {
        logger.trace("Refreshing " + this);
    }
    else {
        logger.debug("Refreshing " + getDisplayName());
    }
}
  • 如果启用了调试日志,则打印当前正在刷新的上下文信息。
  • getDisplayName() 返回的是上下文的名称或类名。

3. 初始化属性源(Property Sources)

initPropertySources();
  • 这是一个钩子方法(hook method) ,供子类重写以添加自定义的属性源。
  • 默认实现为空。
  • 示例:子类可以在这里添加数据库配置、系统参数等自定义属性源。

📌 子类如 GenericWebApplicationContext 会覆盖此方法来添加 Web 环境相关的属性。


4. 验证必须的属性是否都已配置

getEnvironment().validateRequiredProperties();
  • 获取当前环境对象(ConfigurableEnvironment)并调用 validateRequiredProperties()
  • 该方法会检查所有被标记为“required”的属性是否都存在于环境中。
  • 如果有缺失,抛出异常(通常是 MissingRequiredPropertiesException)。

✅ 这个机制可以用来保证某些关键属性(如数据库连接URL、用户名密码)在应用启动前已经正确配置。


5. 保存早期监听器(ApplicationListeners)

if (this.earlyApplicationListeners == null) {
    this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
    this.applicationListeners.clear();
    this.applicationListeners.addAll(this.earlyApplicationListeners);
}
  • 保存或恢复事件监听器集合(即 ApplicationListener)。
  • 在上下文刷新前,有些监听器可能已经被注册(比如通过编程方式添加),这个步骤是为了防止它们在刷新过程中丢失。

📌 earlyApplicationListeners 是一个临时存储结构,在 refresh() 前后用于保留原始监听器状态。


6. 准备早期事件队列

this.earlyApplicationEvents = new LinkedHashSet<>();
  • 创建一个新的集合用于缓存“早期事件”。
  • 在 refresh() 的早期阶段,事件广播器(ApplicationEventMulticaster)还未初始化完成,无法发布事件。
  • 因此,这些事件会被暂存在 earlyApplicationEvents 中,待事件广播器初始化完成后统一发布。

📌 典型使用场景:ContextRefreshedEvent 就是在这里延迟发布的。

obtainFreshBeanFactory

/**
 * Tell the subclass to refresh the internal bean factory.
 * @return the fresh BeanFactory instance
 * @see #refreshBeanFactory()
 * @see #getBeanFactory()
 */
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

1.刷新上下文

方法的代码如下: 这段代码位于AbstractRefreshableApplicationContext抽象类,上文中的 ClassPathXmlApplicationContext间接继承了这个抽象类。

@Override
protected final void refreshBeanFactory() throws BeansException {
    // 销毁已有 Bean 和关闭旧的 BeanFactory
    if (hasBeanFactory()) {
       destroyBeans();
       closeBeanFactory();
    }
    try 
        // 创建新的 DefaultListableBeanFactory 实例
       DefaultListableBeanFactory beanFactory = createBeanFactory();
       beanFactory.setSerializationId(getId());
   
        // 自定义 BeanFactory 属性
        // 这个方法点进去后就是设置是否允许循环依赖和Bean覆盖
       customizeBeanFactory(beanFactory);
  
        // 加载 Bean 定义
       loadBeanDefinitions(beanFactory);
       this.beanFactory = beanFactory;
    }
    catch (IOException ex) {
       throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

对于loadBeanDefinitions(beanFactory)方法,大家点进源码后会发现下面这段代码

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
       reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
       reader.loadBeanDefinitions(configLocations);
    }
}

getConfigLocations()方法就会获取上文中的 configLocations 配置文件,然后进行解析这个xml文件加载Bean。方法嵌套的比较多,这里就不一一展示了,大家可以点击源码自行阅读具体实现。

上下文创建完毕后就调用 getBeanFactory方法返回。

prepareBeanFactory

prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法是 Spring 容器初始化过程中的一部分,主要用于配置 BeanFactory 的基础功能和注册一些必要的依赖。这个方法在 AbstractApplicationContext 类中定义。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置 BeanFactory 使用上下文的类加载器等。
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 配置 BeanFactory 以支持上下文回调。
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(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);
    beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

    // 注册一些默认的可解析依赖。
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 注册一个用于检测内部 Bean 是否为 ApplicationListeners 的后处理器。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 检测是否存在 LoadTimeWeaver 并准备织入(如果存在)。
    if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // 设置一个临时的 ClassLoader 用于类型匹配。
        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());
    }
    if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
        beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
    }
}

详细步骤说明

1. 设置类加载器和其他基础组件
  • setBeanClassLoader() : 设置 BeanFactory 使用的类加载器,通常是从当前上下文中获取的。
  • setBeanExpressionResolver() : 设置一个标准的 Bean 表达式解析器,支持在 Bean 定义中使用 SpEL (Spring Expression Language)。
  • addPropertyEditorRegistrar() : 添加一个属性编辑器注册器,主要用于处理资源类型的属性值(如路径、URL 等),使其能够正确地转换为相应的对象类型。
2. 配置上下文感知接口
  • addBeanPostProcessor(new ApplicationContextAwareProcessor(this)) : 添加一个 ApplicationContextAwareProcessor,它会自动将上下文信息注入到实现了特定接口(如 ApplicationContextAware, ResourceLoaderAware 等)的 Bean 中。
  • 忽略某些依赖接口: 对于某些接口(如 EnvironmentAware),通过 ignoreDependencyInterface() 来告诉 BeanFactory 忽略这些接口作为依赖注入的目标。这样做的目的是避免不必要的依赖注入循环。
3. 注册可解析依赖
  • registerResolvableDependency() : 注册一些常见的可解析依赖类型(如 BeanFactoryResourceLoaderApplicationEventPublisherApplicationContext),使得它们可以直接被自动装配(autowired)。
4. 添加 Bean 后处理器
  • addBeanPostProcessor(new ApplicationListenerDetector(this)) : 添加一个 ApplicationListenerDetector,它会在 Bean 创建过程中检测是否实现了 ApplicationListener 接口,并将其注册为事件监听器。
5. Load-Time Weaving 支持
  • 如果应用上下文中存在名为 loadTimeWeaver 的 Bean,则会添加一个 LoadTimeWeaverAwareProcessor,并设置一个临时的 ClassLoader 用于类型匹配。这主要用于 AOP 功能中的运行时织入。
6. 注册默认的环境 Bean
  • 如果 BeanFactory 中还没有包含特定名称的 Bean,则会注册一些默认的环境相关的单例 Bean,包括:

    • environment: 当前的 Environment 实例。
    • systemProperties: 系统属性。
    • systemEnvironment: 系统环境变量。
    • applicationStartup: 应用启动信息。

postProcessBeanFactory

这个方法允许子类或者外部的扩展点对 BeanFactory 进行进一步定制化处理。这是一个 空实现(no-op) 的方法,在 AbstractApplicationContext 中默认什么都不做。

有一些类重写了这个方法,比如在 AbstractRefreshableWebApplicationContext 上下文中,会重写这个方法来添加 Web 相关的支持:

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 添加 ServletContextAwareProcessor BeanPostProcessor 到 BeanFactory
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    
    // 忽略 ServletContextAware 和 ServletConfigAware 接口作为自动装配的候选者
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
    
    // 注册 Web 应用的作用域(如 request, session)到 BeanFactory
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    
    // 注册环境相关的 Bean(如 servletContext, servletConfig)到 BeanFactory
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

这种定制化让 Spring 容器更好地适应 Web 应用的需求,并提供了更加灵活和强大的功能支持

invokeBeanFactoryPostProcessors

这个方法就很好理解了,在上一个方法 postProcessBeanFactory 中添加了不同环境的BeanFactory实现,这一步就是调用这些方法,代码就不展示了。

registerBeanPostProcessors

这个方法的主要职责是查找并注册所有 BeanPostProcessor 实现类到给定的 BeanFactory 中。这些处理器将在 Bean 实例化和初始化过程中被调用,允许开发者在 Bean 的生命周期不同阶段执行自定义逻辑。点进源码后会发现下面这段代码:

public static void registerBeanPostProcessors(
       ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // WARNING: Although it may appear that the body of this method can be easily
    // refactored to avoid the use of multiple loops and multiple lists, the use
    // of multiple lists and multiple passes over the names of processors is
    // intentional. We must ensure that we honor the contracts for PriorityOrdered
    // and Ordered processors. Specifically, we must NOT cause processors to be
    // instantiated (via getBean() invocations) or registered in the ApplicationContext
    // in the wrong order.
    //
    // Before submitting a pull request (PR) to change this method, please review the
    // list of all declined PRs involving changes to PostProcessorRegistrationDelegate
    // to ensure that your proposal does not result in a breaking change:
    // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(
          new BeanPostProcessorChecker(beanFactory, postProcessorNames, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
       if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
          BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
          priorityOrderedPostProcessors.add(pp);
          if (pp instanceof MergedBeanDefinitionPostProcessor) {
             internalPostProcessors.add(pp);
          }
       }
       else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
          orderedPostProcessorNames.add(ppName);
       }
       else {
          nonOrderedPostProcessorNames.add(ppName);
       }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
       BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
       orderedPostProcessors.add(pp);
       if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
       }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
       BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
       nonOrderedPostProcessors.add(pp);
       if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
       }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

1 取所有 BeanPostProcessor Bean 名称

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
  • 这一步从 BeanFactory 中找出所有实现了 BeanPostProcessor 接口的 Bean。

  • 参数说明:

    • true: 表示只查找非单例但可配置的 Bean。
    • false: 不考虑对象类型的匹配问题。

2️ 添加 BeanPostProcessorChecker

int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, postProcessorNames, beanProcessorTargetCount));
  • 这是一个用于调试的日志检查器。
  • 如果某个 Bean 在 BeanPostProcessor 实例化之前就被创建了,会记录一个提示信息,因为这可能导致某些后处理器无法处理这个 Bean。

3️ 分类处理不同的 BeanPostProcessor

List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();

遍历所有找到的 BeanPostProcessor Bean 名称,并根据它们是否实现了以下接口进行分类:

分类接口处理方式
priorityOrderedPostProcessorsPriorityOrdered第一优先级加载
orderedPostProcessorNamesOrdered第二优先级加载
nonOrderedPostProcessorNames最后加载
internalPostProcessors特殊类型如 MergedBeanDefinitionPostProcessor后续再次注册

4️ 注册 PriorityOrdered 类型的处理器

sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
  • 先对这些处理器排序。
  • 然后依次注册到 BeanFactory 中。

5️ 注册 Ordered 类型的处理器

for (String ppName : orderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    orderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
  • 实例化每个 Ordered 类型的 BeanPostProcessor
  • 如果是内部处理器,加入 internalPostProcessors

6️ 注册没有实现排序接口的普通处理器

for (String ppName : nonOrderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
  • 这些处理器执行顺序不保证,但仍然会被注册。

7️ 重新注册内部处理器(如 AutowiredAnnotationBeanPostProcessor

sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
  • 内部处理器通常需要在整个链表的末尾执行,以确保能够处理所有已经代理或合并定义的 Bean。

8️ 确保 ApplicationListenerDetector 放到最后

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
  • 这个特殊的处理器用于检测哪些 Bean 是 ApplicationListener
  • 放到最后是为了确保能正确识别代理后的 Bean(例如 AOP 代理)。

initMessageSource

它在 Spring 容器初始化过程中负责 初始化或注册 MessageSource,这是 Spring 支持国际化(i18n)的核心组件。代码如下:

protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
       this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
       // Make MessageSource aware of parent MessageSource.
       if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource hms &&
             hms.getParentMessageSource() == null) {
          // Only set parent context as parent MessageSource if no parent MessageSource
          // registered already.
          hms.setParentMessageSource(getInternalParentMessageSource());
       }
       if (logger.isTraceEnabled()) {
          logger.trace("Using MessageSource [" + this.messageSource + "]");
       }
    }
    else {
       // Use empty MessageSource to be able to accept getMessage calls.
       DelegatingMessageSource dms = new DelegatingMessageSource();
       dms.setParentMessageSource(getInternalParentMessageSource());
       this.messageSource = dms;
       beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
       if (logger.isTraceEnabled()) {
          logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
       }
    }
}

该方法的主要职责:

  • 查找是否定义了自定义的 messageSource Bean
  • 如果没有,则创建一个默认的 DelegatingMessageSource 实例
  • 设置父上下文的消息源(如果有),形成消息继承链
  • 将 MessageSource 注册为单例 Bean 并赋值给上下文

对于 initApplicationEventMulticaster方法代码的实现逻辑和这个差不多,就不单独介绍了

总结

每个方法的作用如下:

阶段方法名所属类主要作用核心逻辑说明
1. 准备刷新prepareRefresh()AbstractApplicationContext初始化上下文环境,准备刷新容器设置启动时间、初始化属性源、校验必需的配置项
2. 获取 BeanFactoryobtainFreshBeanFactory()AbstractApplicationContext创建或获取一个 ConfigurableListableBeanFactory 实例刷新 BeanFactory,加载并解析 Bean 定义(如 XML 或注解)
3. 配置 BeanFactoryprepareBeanFactory(ConfigurableListableBeanFactory)AbstractApplicationContext为 BeanFactory 添加基础支持功能设置 ClassLoader、添加 PropertyEditor、注册默认的 Environment Bean 等
4. 子类扩展点postProcessBeanFactory(ConfigurableListableBeanFactory)AbstractApplicationContext(子类实现)允许子类对 BeanFactory 做进一步定制如 Web 应用上下文可在此添加 Web 相关组件
5. 调用 BeanFactory 后处理器invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory)PostProcessorRegistrationDelegate调用所有 BeanFactoryPostProcessor修改或扩展 BeanDefinition(如 @ComponentScan 的处理)
6. 注册 Bean 后处理器registerBeanPostProcessors(ConfigurableListableBeanFactory)PostProcessorRegistrationDelegate注册 BeanPostProcessor 实现类如 AOP 功能依赖的 InstantiationAwareBeanPostProcessor
7. 初始化消息源initMessageSource()AbstractApplicationContext初始化国际化消息支持查找自定义 messageSource,否则创建默认 DelegatingMessageSource
8. 初始化事件广播器initApplicationEventMulticaster()AbstractApplicationContext初始化事件发布机制使用默认或自定义的 ApplicationEventMulticaster
9. 自定义刷新逻辑onRefresh()AbstractApplicationContext(子类重写)子类提供特定于上下文的刷新行为如 Web 容器中启动嵌入式服务器
10. 注册监听器registerListeners()AbstractApplicationContext注册所有 ApplicationListener Bean保证事件能被监听和响应
11. 初始化单例 BeanfinishBeanFactoryInitialization(ConfigurableListableBeanFactory)AbstractApplicationContext实例化所有非懒加载的单例 Bean包括依赖注入、AOP 代理生成等

感谢阅读!