浅析 Spring 启动过程:从源码到焦点方法

[复制链接]
发表于 2025-8-31 12:00:21 | 显示全部楼层 |阅读模式

在 Java 企业级开发中,Spring 框架是最常用的底子框架之一。相识 Spring 的启动过程,对于理解 Spring 的工作原理、优化应用性能以及排查问题都有着至关重要的作用。本文将结合纯 Spring 的注解方式启动类,深入解读 Spring 启动过程的源码,重点分析refresh()方法及其包含的关键步骤。
一、Spring 注解方式启动类 Demo

起首,我们创建一个简单的 Spring 项目,通过注解方式启动 Spring 容器
  1. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. @ComponentScan("com.coderzpw")      // 扫描该路径下的包
  5. @Configuration
  6. public class AppConfig {
  7.     public static void main(String[] args) {
  8.         // Spring容器启动
  9.         AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  10.         // 可以在这里获取Bean进行后续操作
  11.         // 容器关闭
  12.         applicationContext.close();
  13.     }
  14. }
复制代码
在上述代码中:


  • @Configuration注解表明该类是一个设置类,用于替代传统的 XML 设置文件。
  • @ComponentScan("com.coderzpw") 注解用于扫描指定包及其子包下的所有@Component、@Service、@Repository、@Controller等注解标注的类,并将它们注册为 Spring 容器中的 Bean。
  • 在main方法中,通过AnnotationConfigApplicationContext来创建 Spring 应用上下文,传入设置类AppConfig.class,从而启动 Spring 容器。
二、Spring 启动过程源码解析

当我们调用AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);时,Spring 的启动过程便开始了。接下来我们深入源码,一探毕竟。
​AnnotationConfigApplicationContext构造函数

  1. public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
  2.         this();
  3.         register(annotatedClasses);
  4.         refresh();
  5. }
复制代码
上述代码中:


  • this()调用了无参构造函数,在无参构造函数中会初始化reader和scanner,用于读取设置类和扫描 Bean。
  • register(componentClasses)方法将传入的设置类注册到容器中。
  • 最后调用的refresh()方法是 Spring 启动过程的焦点,它完成了 Spring 容器的初始化、Bean 的加载、设置的解析等一系列关键操纵
refresh()方法详解

对 BeanPostProcessor、BeanFactoryPostProcessor不熟悉的同学可以查察下面文章:
【Spring BeanFactoryPostProcessor:机制解读与代码实践】
【Spring BeanPostProcessor:机制解读与代码实践】

refresh()方法位于AbstractApplicationContext类中,其源码如下:
  1. @Override
  2. public void refresh() throws BeansException, IllegalStateException {
  3.         synchronized (this.startupShutdownMonitor) {
  4.                 // 准备上下文环境,记录启动时间,标记活动状态等
  5.                 prepareRefresh();
  6.                 // 告诉子类刷新内部bean工厂
  7.                 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  8.                 // 准备bean工厂,设置一些属性,如类加载器、表达式解析器等
  9.                 prepareBeanFactory(beanFactory);
  10.                 try {
  11.                         // 允许子类在bean工厂准备好后进行进一步的设置
  12.                         postProcessBeanFactory(beanFactory);
  13.                         // 执行BeanFactoryPostProcessor接口的实现类,在bean实例化之前修改bean的定义
  14.                         invokeBeanFactoryPostProcessors(beanFactory);
  15.                         // 注册BeanPostProcessor接口的实现类,用于在bean实例化、配置和初始化前后进行处理
  16.                         registerBeanPostProcessors(beanFactory);
  17.                         // 初始化消息源,用于国际化等功能
  18.                         initMessageSource();
  19.                         // 初始化应用事件广播器
  20.                         initApplicationEventMulticaster();
  21.                         // 留给子类初始化其他特殊bean的钩子方法
  22.                         onRefresh();
  23.                         // 注册监听器到事件广播器
  24.                         registerListeners();
  25.                         // 实例化所有剩余的非惰性单例bean
  26.                         finishBeanFactoryInitialization(beanFactory);
  27.                         // 完成刷新过程,发布容器刷新完成事件等
  28.                         finishRefresh();
  29.                 }
  30.                 catch (BeansException ex) {
  31.                         if (logger.isWarnEnabled()) {
  32.                                 logger.warn("Exception encountered during context initialization - " +
  33.                                                 "cancelling refresh attempt: " + ex);
  34.                         }
  35.                         // Destroy already created singletons to avoid dangling resources.
  36.                         destroyBeans();
  37.                         // Reset 'active' flag.
  38.                         cancelRefresh(ex);
  39.                         // Propagate exception to caller.
  40.                         throw ex;
  41.                 }
  42.                 finally {
  43.                         // Reset common introspection caches in Spring's core, since we
  44.                         // might not ever need metadata for singleton beans anymore...
  45.                         resetCommonCaches();
  46.                 }
  47.         }
  48. }
复制代码
refresh()方法主要包含 12 个步骤,每个步骤都承担着不同的职责:

  • prepareRefresh();
    【准备工作】
    作用:在开始刷新容器之前,进行一些准备工作,如设置容器的启动时间、标记容器为活泼状态、清除缓存等。这是 IoC 容器启动的前奏,为后续的初始化操纵做好准备。
  • ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    【获取Bean工厂】
    作用获取或创建一个新的 BeanFactory 实例,BeanFactory 是 Spring IoC 容器的焦点,负责管理 Bean 的定义和实例化。这个步骤是 IoC 容器启动的底子,后续的 Bean 加载和创建都依赖于BeanFactory。(重要:XML设置形势下,加载BeanDefinition就是在这个步骤,具体方法步骤:obtainFreshBeanFactory -> refreshBeanFactory -> loadBeanDefinitions
  • prepareBeanFactory(beanFactory);
    【设置 Bean 工厂】【为BeanFactory做底子的设置】
    作用:对获取到的 BeanFactory 进行一些默认设置,如设置类加载器、添加默认的Bean 后置处理器(例如ApplicationContextAwareProcessor、ApplicationListenerDetector)、设置表达式解析器等。这些设置会影响后续 Bean 的创建和初始化过程。
  • postProcessBeanFactory(beanFactory);
    【后置处理 Bean 工厂】【子类做后置扩展处理】
    作用:答应子类对 BeanFactory 进行额外的后置处理,例如注册自定义的 BeanPostProcessor 或 BeanFactoryPostProcessor。这为开发者提供了扩展 IoC 容器功能的机会。
  • invokeBeanFactoryPostProcessors(beanFactory);
    【调用注册的BeanFactoryPostProcessor实现类】
    作用调用所有注册的 BeanFactoryPostProcessor 实现类,这些处理器可以在 Bean 定义加载完成后、Bean 实例化之前对 Bean 定义进行修改。通过这个步骤,开发者可以动态地修改 Bean 的定义信息。
  • registerBeanPostProcessors(beanFactory);
    【注册 BeanPostProcessor的实现类】【只注册、不调用】
    作用注册所有的 BeanPostProcessor实现类,这些处理器会在Bean实例化、设置和初始化前后进行额外的处理。例如,AutowiredAnnotationBeanPostProcessor可以处理@Autowired注解,实现主动装配功能
  • initMessageSource();
    【初始化消息源】
    作用初始化消息源,用于支持国际化和消息解析。这在须要处理多语言的应用程序中非常有用。
  • initApplicationEventMulticaster();
    【初始化应用[事件广播器]】
    [事件广播器]:负责将事件广播给所有注册的监听器。
    [事件发布者(ApplicationEventPublisher)]:负责发布事件
    [事件监听器(ApplicationListener)]:负责监听特定类型的事件
    作用初始化应用事件广播器,用于发布和监听应用程序中的事件。Spring 的事件机制答应组件之间进行松耦合的通讯。
  • onRefresh();
    【留给子类扩展】【空实现】【子类特定的刷新操纵】
    作用:答应子类实现特定的刷新逻辑,例如在 WebApplicationContext 中,会创建和初始化 Servlet 上下文。
  • registerListeners();
    【注册监听器】
    作用注册应用程序中的事件监听器,这些监听器会监听由事件广播器发布的事件,并执行相应的处理逻辑。
  • finishBeanFactoryInitialization(beanFactory);
    【实例化所有剩余的单例 Bean】【Bean 实例化、初始化、BeanPostProcessor的执行】
    作用:实例化所有剩余的单例 Bean,这是 IoC 容器启动的焦点步骤之一。在这个过程中,BeanFactory 会根据 Bean 定义创建 Bean 实例,并进行依赖注入和初始化操纵。
  • finishRefresh();
    【完成刷新】
    作用完成容器的刷新工作,清除缓存、发布容器刷新完成事件等。此时,IoC 容器已经完全启动并可以正常利用。
三、refresh()的焦点方法/步骤

obtainFreshBeanFactory() - 获取Bean工厂

  1. protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
  2.     refreshBeanFactory();    // 触发BeanDefinition加载
  3.     return getBeanFactory();
  4. }
复制代码
obtainFreshBeanFactory()是Spring容器启动流程中的焦点方法,其焦点性表如今:


  • BeanFactory生命周期起点:负责创建或刷新BeanFactory实例,是IoC容器诞生的起点
  • 设置加载入口:触发XML设置的解析流程,将设置转化为可操纵的BeanDefinition对象
   BeanDefinition加载流程解析
  1. 传统Spring项目(XML设置为例)
焦点步骤


  • refreshBeanFactory():销毁旧容器 → 创建DefaultListableBeanFactory → 加载BeanDefinition
  • loadBeanDefinitions():通过XmlBeanDefinitionReader解析XML文件,天生BeanDefinition并注册
源码示例
  1. @Override
  2. protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
  3.         XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
  4.         // ....
  5.         initBeanDefinitionReader(beanDefinitionReader);
  6.         loadBeanDefinitions(beanDefinitionReader);
  7. }
复制代码
2. SpringBoot项目(注解驱动)


  • 实现差别:

    • 本质利用GenericApplicationContext代替AbstractRefreshableApplicationContext
    • obtainFreshBeanFactory()仅设置序列化ID,不执行设置加载

  • 实际加载入口:

    • ConfigurationClassPostProcessor(后置处理器)扫描@Configuration类
    • @ComponentScan注解触发包扫描,动态注册BeanDefinition

prepareBeanFactory(beanFactory) - 设置 Bean 工厂

  1. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  2.         // 告诉内部 Bean 工厂使用上下文的类加载器等。
  3.         beanFactory.setBeanClassLoader(getClassLoader());
  4.         beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  5.         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
  6.        
  7.         // 注册ApplicationContextAwareProcessor (ApplicationContextAwareProcessor负责处理实现了ApplicationContextAware的类)
  8.         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  9.         //
  10.         // 注册早期后处理器,用于将内部 bean 检测为 ApplicationListeners。
  11.         beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  12.         // ...
  13.         // 注册默认的 环境Bean
  14.         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  15.                 beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  16.         }
  17.         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  18.                 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  19.         }
  20.         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  21.                 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  22.         }
  23. }
复制代码
焦点设置


  • 设置类加载器
  • 添加默认的Bean 后置处理器(例如ApplicationContextAwareProcessor、ApplicationListenerDetector)
  • 注册默认的 情况bean
invokeBeanFactoryPostProcessors() - 调用注册的BeanFactoryPostProcessor实现类

  1. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  2.         // 【核心】调用 BeanFactoryPostProcessors
  3.         PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  4.         // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
  5.         // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
  6.         // ...
  7. }
复制代码
进入invokeBeanFactoryPostProcessors:
  1. public static void invokeBeanFactoryPostProcessors(
  2.                 ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3.         // 【 1. 处理所有 BeanDefinitionRegistryPostProcessor(子接口)】
  4.         if (beanFactory instanceof BeanDefinitionRegistry) {
  5.                 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  6.                 List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
  7.                 List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
  8.                                 new LinkedList<BeanDefinitionRegistryPostProcessor>();
  9.        
  10.                 // 分阶段处理:PriorityOrdered → Ordered → 普通实现
  11.        
  12.                 // 执行 PriorityOrdered
  13.                 invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
  14.        
  15.                 // 执行 Ordered
  16.                 invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
  17.        
  18.                 // 执行 普通实现
  19.                 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
  20.                 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  21.         }
  22.        
  23.         else {
  24.                 // Invoke factory processors registered with the context instance.
  25.                 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  26.         }
  27.        
  28.         // ...
  29.        
  30.         // 【 2. 处理所有 BeanFactoryPostProcessor】
  31.         // 分阶段处理:PriorityOrdered → Ordered → 普通实现
  32.         List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  33.         List<String> orderedPostProcessorNames = new ArrayList<String>();
  34.         List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
  35.         for (String ppName : postProcessorNames) {
  36.                 if (processedBeans.contains(ppName)) {
  37.                         // skip - already processed in first phase above
  38.                 }
  39.                 else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  40.                         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
  41.                 }
  42.                 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  43.                         orderedPostProcessorNames.add(ppName);
  44.                 }
  45.                 else {
  46.                         nonOrderedPostProcessorNames.add(ppName);
  47.                 }
  48.         }
  49.        
  50.         // 执行 PriorityOrdered
  51.         invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  52.        
  53.         // 执行 Ordered
  54.         invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  55.        
  56.         // 执行 普通实现
  57.         invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  58.         // ...
  59. }
复制代码
具体执行方法:invokeBeanFactoryPostProcessors
  1. /**
  2. * 调用给定的BeanFactoryPostProcessor bean。
  3. */
  4. private static void invokeBeanFactoryPostProcessors(
  5.                 Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
  6.         for (BeanFactoryPostProcessor postProcessor : postProcessors) {
  7.             // 执行具体的postProcessBeanFactory方法
  8.                 postProcessor.postProcessBeanFactory(beanFactory);
  9.         }
  10. }
复制代码
此中ConfigurationClassPostProcessor是BeanFactoryPostProcessor的子类,会在该阶段执行厥后置处理逻辑。负责解析 @Configuration 类及其注解(如 @ComponentScan、@Bean),动态注册新的 BeanDefinition
ConfigurationClassPostProcessor焦点功能:

  • 扫描设置类: 辨认 @Configuration 类,解析其上的 @ComponentScan、@Import 等注解
  • 处理条件注解: 根据 @Conditional 注解判定是否注册对应的 BeanDefinition
finishBeanFactoryInitialization() - 实例化、初始化所有剩余的单例 Bean【重要】【重要】【重要】

  1. protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  2.         // ...
  3.         // 实例化所有剩余的 (非 lazy-init) 单例。【核心】【重要】【bean实例化 -> 属性填充 -> 初始化】
  4.         beanFactory.preInstantiateSingletons();
  5. }
复制代码
finishBeanFactoryInitialization() 方法焦点作用总结:

  • 初始化底子服务

    • 设置类型转换服务(ConversionService),处理 @Value 和属性注入的类型转换

  • 冻结 Bean 设置

    • 调用 freezeConfiguration(),停止修改 BeanDefinition,确保后续实例化过程的线程安全

  • 实例化非懒加载单例 Bean

    • 遍历所有 BeanDefinition,触发 getBean() 实例化非抽象、单例且非懒加载的 Bean
    • 特殊处理 FactoryBean:根据 SmartFactoryBean.isEagerInit() 判定是否立即天生目的对象

  • 初始化回调与扩展

    • 触发 SmartInitializingSingleton.afterSingletonsInstantiated(),在所有单例创建完成后执行自定义逻辑
    • 处理 LoadTimeWeaverAware 接口,支持类加载期字节码增强(如 AspectJ LTW)

  • 资源回收与优化

    • 释放临时类加载器(TempClassLoader),避免内存走漏

该方法涉及 Spring IoC 最复杂的实例化阶段,包括 bean的实例化属性填充(解决循环依赖)、BeanPostProcesser的前置处理(部分Aware处理逻辑)、bean的初始化BeanPostProcesser的后置处理(AOP 署理的天生时机)等细节
一篇文章是讲授不清楚finishBeanFactoryInitialization()的,请期待后续总结 ✿ヽ(°▽°)ノ✿

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表