当前位置: 首页 > news >正文

【Spring Boot刷新上下文核心流程详解】

Spring Boot 刷新上下文核心流程详解

一、前言

在使用 Spring Boot 启动应用时,控制台会打印出一大串日志,其中最核心的启动动作之一就是 刷新上下文(refresh)。
refresh 方法不仅负责 Bean 的创建与初始化,还涉及监听器、国际化、多环境配置等多个模块,是 Spring Boot 启动的核心环节。
本文将结合源码,带你从入口到细节剖析刷新上下文的全过程。

二、入口位置

实例方法SpringApplication#run
在这里插入图片描述
好,那我帮你写一篇**《Spring Boot 刷新上下文核心流程详解》**的 CSDN 博客文章,结构会清晰、逻辑循序渐进,既有源码分析又有配图思路,读者看完能对整个 refresh 流程有一个比较完整的理解。


Spring Boot 刷新上下文核心流程详解

一、前言

在使用 Spring Boot 启动应用时,控制台会打印出一大串日志,其中最核心的启动动作之一就是 刷新上下文(refresh)
refresh 方法不仅负责 Bean 的创建与初始化,还涉及监听器、国际化、多环境配置等多个模块,是 Spring Boot 启动的核心环节。
本文将结合源码,带你从入口到细节剖析刷新上下文的全过程。


二、入口位置

Spring Boot 的启动入口通常是:

SpringApplication.run(Application.class, args);

调用链简化如下:

SpringApplication.run()-> SpringApplication.refreshContext()-> AbstractApplicationContext.refresh()

核心就在 AbstractApplicationContext.refresh() 方法中,这也是所有 Spring 上下文实现(如 AnnotationConfigServletWebServerApplicationContext)的基础模板方法。


三、源码流程概览

AbstractApplicationContext# refresh() 的主要执行步骤如下(简化版):

public void refresh() throws BeansException, IllegalStateException {this.startupShutdownLock.lock();try {this.startupShutdownThread = Thread.currentThread();StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");this.prepareRefresh();ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();this.prepareBeanFactory(beanFactory);try {this.postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");this.invokeBeanFactoryPostProcessors(beanFactory);this.registerBeanPostProcessors(beanFactory);beanPostProcess.end();this.initMessageSource();this.initApplicationEventMulticaster();this.onRefresh();this.registerListeners();this.finishBeanFactoryInitialization(beanFactory);this.finishRefresh();} catch (Error | RuntimeException var12) {if (this.logger.isWarnEnabled()) {this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var12);}this.destroyBeans();this.cancelRefresh(var12);throw var12;} finally {contextRefresh.end();}} finally {this.startupShutdownThread = null;this.startupShutdownLock.unlock();}}

四、各步骤详解

1. prepareRefresh():刷新前准备

  • 设置启动时间
  • 初始化 active 标志位
  • 初始化 PropertySources(环境变量、配置文件等)
  • 校验必须的配置

作用:确保上下文环境准备好,避免启动中途缺配置。


2. obtainFreshBeanFactory():获取 BeanFactory

整体流程
AbstractRefreshableApplicationContext#obtainFreshBeanFactory() -->AbstractRefreshableApplicationContext#refreshBeanFactory -->createBeanFactory() -->loadBeanDefinitions()
在这里插入图片描述
最后执行AnnotationConfigWebApplicationContext#loadBeanDefinitions(刷新上下文最核心的方法)

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {AnnotatedBeanDefinitionReader reader = this.getAnnotatedBeanDefinitionReader(beanFactory);ClassPathBeanDefinitionScanner scanner = this.getClassPathBeanDefinitionScanner(beanFactory);BeanNameGenerator beanNameGenerator = this.getBeanNameGenerator();if (beanNameGenerator != null) {reader.setBeanNameGenerator(beanNameGenerator);scanner.setBeanNameGenerator(beanNameGenerator);beanFactory.registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", beanNameGenerator);}ScopeMetadataResolver scopeMetadataResolver = this.getScopeMetadataResolver();if (scopeMetadataResolver != null) {reader.setScopeMetadataResolver(scopeMetadataResolver);scanner.setScopeMetadataResolver(scopeMetadataResolver);}if (!this.componentClasses.isEmpty()) {if (this.logger.isDebugEnabled()) {this.logger.debug("Registering component classes: [" + StringUtils.collectionToCommaDelimitedString(this.componentClasses) + "]");}reader.register(ClassUtils.toClassArray(this.componentClasses));}if (!this.basePackages.isEmpty()) {if (this.logger.isDebugEnabled()) {this.logger.debug("Scanning base packages: [" + StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]");}scanner.scan(StringUtils.toStringArray(this.basePackages));}

主要流程

  1. 执行this.createBeanFactory()默认bean工厂:DefaultListableBeanFactory实例创建
  2. 从核心触发loadBeanDefinitions触发:创建对应的 BeanDefinition 将其注册到 BeanDefinitionRegistry
    • AnnotatedBeanDefinitionReader#register方法进行对@Component等注解进行解析注册成对应的 BeanDefinition (bean的元数据,包括bean名称,作用域等,类似注册bean之前得先准备好bean的材料,才能注册)
    • ClassPathBeanDefinitionScanner#scan方法对 @ComponentScan的basepack进行解析,扫描包路径下的注解注册BeanDefinition。
  3. 返回对应的DefaultListableBeanFactory工厂实例

3. prepareBeanFactory():BeanFactory 预准备

在这里插入图片描述

4. postProcessBeanFactory():子类扩展

添加相关 Bean 后处理器,为后续创建好的 bean 可做扩展。

5. invokeBeanFactoryPostProcessors():调用 BeanFactory 后置处理器

  • 先执行 BeanDefinitionRegistryPostProcessor(可修改 Bean 定义)
  • 再执行 BeanFactoryPostProcessor(可修改 BeanFactory 配置)

典型例子:
ConfigurationClassPostProcessor

  • 会解析 @Configuration 类:
  • 处理 @Bean 方法 → 新注册对应的 BeanDefinition
  • 处理 @ComponentScan → 扫描新包,注册新 BeanDefinition
  • 处理 @Import、@ImportResource → 引入额外 BeanDefinition,Import其实也是自动装配原理的第一个最重要的一点
    流程是
refresh()→ invokeBeanFactoryPostProcessors()中的postProcessBeanDefinitionRegistry()→ ConfigurationClassPostProcessor#processConfigBeanDefinitions()→ ConfigurationClassParser#parse→ ConfigurationClassParser#processImports()→ AutoConfigurationImportSelector#selectImports()

6. registerBeanPostProcessors():注册 Bean 后置处理器

  • AOP、@Autowired、@ConfigurationProperties 等功能都依赖它
  • 会在 Bean 实例化前后执行拦截逻辑

7. initMessageSource():国际化

  • 如果用户定义了 messageSource Bean,则使用用户的
  • 否则创建 DelegatingMessageSource 作为默认实现

8. initApplicationEventMulticaster():事件广播器

  • 如果用户定义了 applicationEventMulticaster,则使用用户的
  • 否则创建默认的 SimpleApplicationEventMulticaster

9. onRefresh():子类刷新逻辑

  • Web 环境下启动 Tomcat/Jetty/Undertow 内嵌容器
  • 加载 DispatcherServlet 等 MVC 核心组件

10. registerListeners():注册监听器

  • 注册所有 ApplicationListener 类型的 Bean
  • 处理启动前缓存的早期事件

11. finishBeanFactoryInitialization():根据实例化所有非懒加载单例

  • 根据已有的 BeanDefinition 注册对应的bean
  • 依赖注入
  • 初始化方法执行(@PostConstructInitializingBean 等)

12. finishRefresh():收尾工作

  • 清理缓存
  • 发布 ContextRefreshedEvent
  • 标记启动完成

五、流程图

prepareRefresh()↓
obtainFreshBeanFactory()↓
prepareBeanFactory()↓
postProcessBeanFactory()↓
invokeBeanFactoryPostProcessors()↓
registerBeanPostProcessors()↓
initMessageSource()↓
initApplicationEventMulticaster()↓
onRefresh()↓
registerListeners()↓
finishBeanFactoryInitialization()↓
finishRefresh()

六、总结

refresh() 就像 Spring Boot 启动的总指挥,控制了从配置准备 → BeanFactory 构建 → Bean 创建 → 事件发布的全流程。
理解它,不仅能帮助我们定位启动问题,还能在做框架扩展、定制化 Bean 加载逻辑时得心应手。

http://www.dtcms.com/a/324767.html

相关文章:

  • UNIVERSAL IMAGE RESTORATION PRE-TRAINING VIA DEGRADATION CLASSIFICATION
  • 【Python 工具人快餐 · 第 5 份】
  • 1. 电阻选型
  • 云服务器最新版MySQL 安装步骤
  • jdk17下载安装教程【超详细图文】
  • 零基础学习jQuery第二天
  • 在windows安装colmap并在cmd调用
  • json-fortran库的使用
  • TS 编译原理,提供的 API
  • Angular初学者入门第二课——.ts、.d.ts、.state.ts的区别(精品)
  • Perplexity 为特朗普 Truth Social 提供技术支持
  • 深入解析微服务分布式事务的原理与优化实践
  • 极移(Polar Motion):概念、原因、影响及坐标转换计算
  • 下载UOS桌面专业版系统镜像
  • 计算机视觉(CV)——图像相关基本概念
  • 【redis初阶】------redis客户端(1)
  • Node.js面试题及详细答案120题(01-15) -- 基础概念篇
  • Leaflet地图高亮与编辑功能实现
  • 【最后203篇系列】031 构建MCP尝试
  • signed 和 unsigned 类型说明符
  • 嵌套-列表存储字典,字典存储列表,字典存储字典
  • Linux 路由子系统深度分析:框架、实现与代码路径
  • web刷题3
  • 商业解决方案技术栈总结
  • Python 获取对象信息的所有方法
  • 基于Spring Boot和SSE的实时消息推送系统
  • 三数之和 Java
  • 人工智能系列(7)人工神经网络中的无监督学习
  • C语言-数组和指针练习题合集(一)
  • C语言深度剖析