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

Spring Boot 启动加载执行链路分析

看源码太枯燥,我们学思维就好;细节不深究,框架只要搭起来,剩下的就是按部就班的填空了。

一、核心启动流程概览

在这里插入图片描述


二、详细执行链路分析

1. 入口:main() 方法

码友们肯定都知道,SpringBoot的启动,只需要依赖web,然后再写以一个如下的main启动方法,就可以搭建起一个web服务了。

聪明的码友如果想知道:在main运行的那一刻,SpringBoot框架到底做了哪些事情?可以看看SpringBoot 启动入口深度解析:main方法执行全流程

@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args); // 启动入口}
}

主类上需要添加@SpringBootApplication,不加就会报错

2. SpringApplication 初始化

// SpringApplication 构造方法核心逻辑
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();// 推断应用类型// 加载扩展点this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 加载Listenerthis.mainApplicationClass = deduceMainApplicationClass();
}

关键步骤:

  • 推断应用类型:检查类路径(Servlet/Reactive/None)
  • 加载spring.factories:从META-INF/spring.factories加载扩展点
  • 初始化引导注册器:Spring Boot 3.0+ 新增BootstrapRegistry机制

3. 环境准备(Environment

// SpringApplication.run() → prepareEnvironment()
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {// 1. 创建环境实例ConfigurableEnvironment environment = getOrCreateEnvironment();// 2. 配置环境(命令行参数、Profile 等)configureEnvironment(environment, applicationArguments.getSourceArgs());// 3. 附加配置属性源(支持 Spring Boot 配置绑定)ConfigurationPropertySources.attach(environment);// 4. 发布 "环境准备完成" 事件(允许监听器修改环境)listeners.environmentPrepared(bootstrapContext, environment);// 5. 调整默认属性源位置(确保优先级正确)DefaultPropertiesPropertySource.moveToEnd(environment);// 6. 校验环境前缀属性(防止非法配置)Assert.state(!environment.containsProperty("spring.main.environment-prefix"),"Environment prefix cannot be set via properties.");// 7. 将环境属性绑定到 SpringApplication 对象bindToSpringApplication(environment);// 8. 环境类型转换(非自定义环境时)if (!this.isCustomEnvironment) {EnvironmentConverter environmentConverter = new EnvironmentConverter(getClassLoader());environment = environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());}// 9. 重新附加配置属性源(确保转换后属性源正确)ConfigurationPropertySources.attach(environment);return environment;
}

执行顺序:

  1. 根据应用类型(Servlet/Reactive/None)创建对应的环境对象;如StandardServletEnvironment(Web应用)
  2. 加载配置源(application.properties/application.yml)(–spring.profiles.active 参数
  3. 发布ApplicationEnvironmentPreparedEvent
    • 触发ConfigFileApplicationListener加载配置文件
    • 触发LoggingApplicationListener初始化日志系统

4. 创建应用上下文(ApplicationContext

// SpringApplication.run() → createApplicationContext()
protected ConfigurableApplicationContext createApplicationContext() {return this.applicationContextFactory.create(this.webApplicationType);
}
// 默认创建 AnnotationConfigServletWebServerApplicationContext(Web应用)

创建的应用上下文类型:

应用类型上下文实现类说明
SERVLETAnnotationConfigServletWebServerApplicationContext支持 Servlet Web 应用(Tomcat/Jetty),整合了 Web 服务器启动
REACTIVEAnnotationConfigReactiveWebServerApplicationContext支持响应式 Web 应用(Netty/WebFlux),内置响应式服务器启动
NONEAnnotationConfigApplicationContext标准非 Web 应用上下文,仅处理 Spring Bean 容器
  1. applicationContextFactory 的来源
    • 默认使用 ApplicationContextFactory.DEFAULT 实现
    • 可通过 SpringApplication.setApplicationContextFactory() 自定义
  2. webApplicationType的确定
    SpringApplication 构造阶段通过以下方式确定:
this.webApplicationType = WebApplicationType.deduceFromClasspath();

根据类路径推断应用类型:

  • 存在 DispatcherHandlerREACTIVE

  • 存在 ServletConfigurableWebApplicationContextSERVLET

  • 其他 → NONE (普通 Java 应用)

  1. 工厂创建逻辑 (ApplicationContextFactory.create())

5. 准备上下文(prepareContext()

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {// 1. 设置环境到上下文context.setEnvironment(environment);// 2. 后处理应用上下文postProcessApplicationContext(context);// 3. 处理AOT生成的初始化器addAotGeneratedInitializerIfNecessary(this.initializers);// 4. 应用初始化器applyInitializers(context);// 5. 发布ContextPrepared事件listeners.contextPrepared(context);// 6. 关闭引导上下文并注册bootstrapContext.close(context);// 7. 记录启动信息if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// 8. 注册关键单例BeanConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}// 9. 配置BeanFactory策略if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {// 设置循环引用策略autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences);if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {// 设置Bean定义覆盖策略listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}// 10. 处理延迟初始化if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// 11. 添加属性源排序处理器context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));// 12. 加载主配置源if (!AotDetector.useGeneratedArtifacts()) {Set<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");load(context, sources.toArray(new Object[0]));}// 13. 发布ContextLoaded事件listeners.contextLoaded(context);
}

核心步骤:

  1. 上下文基础配置
    • 设置环境对象(context.setEnvironment(environment)
    • 执行上下文后处理(postProcessApplicationContext),如添加资源加载器
    • 应用所有初始化器(applyInitializers),执行自定义初始化逻辑
  2. 事件通知与引导关闭
    • 发布 ContextPreparedEvent 事件(listeners.contextPrepared
    • 关闭引导上下文(bootstrapContext.close),将引导阶段单例Bean迁移至主上下文
  3. 关键Bean注册
    • 注册启动参数Bean(springApplicationArguments
    • 注册Banner打印对象(springBootBanner
    • 配置BeanFactory策略(循环引用/Bean覆盖等)
  4. 特殊处理
    • 添加懒加载处理器(若启用全局懒加载)
    • 添加属性源排序处理器(确保配置优先级)
    • 加载主配置源(getAllSources() + load()
  5. 最终事件通知
    • 发布 ContextLoadedEvent 事件(listeners.contextLoaded),允许最终调整上下文

6. 刷新上下文(refreshContext() → 核心!)

// AbstractApplicationContext.refresh()
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 阶段0: 刷新准备StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");this.prepareRefresh(); // 准备刷新上下文// 阶段1: 获取新BeanFactoryConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();// 阶段2: 配置BeanFactorythis.prepareBeanFactory(beanFactory);try {// 阶段3: 后处理BeanFactorythis.postProcessBeanFactory(beanFactory);// 阶段4: 执行BeanFactory后处理器StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");this.invokeBeanFactoryPostProcessors(beanFactory); // 关键:加载配置类/配置属性this.registerBeanPostProcessors(beanFactory);      // 注册Bean后处理器beanPostProcess.end();// 阶段5: 初始化消息源this.initMessageSource();// 阶段6: 初始化事件广播器this.initApplicationEventMulticaster();// 阶段7: 扩展点:子类初始化特殊Beanthis.onRefresh(); // Spring Boot 在此启动Web服务器// 阶段8: 注册监听器this.registerListeners();// 阶段9: 完成BeanFactory初始化this.finishBeanFactoryInitialization(beanFactory); // 实例化所有非懒加载单例// 阶段10: 完成刷新this.finishRefresh(); // 发布ContextRefreshedEvent事件} catch (BeansException ex) {// 异常处理:销毁已创建Bean并取消刷新this.destroyBeans();this.cancelRefresh(ex);throw ex;} finally {// 清理缓存this.resetCommonCaches();contextRefresh.end();}}
}

关键扩展点详解:

1. invokeBeanFactoryPostProcessors() - 自动配置入口
this.invokeBeanFactoryPostProcessors(beanFactory);

扩展机制

  • 执行 ConfigurationClassPostProcessor处理 @Configuration
  • Spring Boot 关键:触发 AutoConfigurationImportSelector
    • 扫描 META-INF/spring.factories 加载自动配置类
    • 执行条件注解过滤 (@ConditionalOnClass等)
    • 加载顺序控制:@AutoConfigureOrder, @AutoConfigureBefore/After

典型流程

在这里插入图片描述

2. onRefresh() - 内嵌服务器启动
protected void onRefresh() {super.onRefresh();createWebServer(); // Spring Boot 扩展
}

扩展实现:

  • ServletWebServerApplicationContext 中:
protected void onRefresh() {super.onRefresh();try {createWebServer(); // 创建并启动Tomcat/Jetty/Undertow} catch (Throwable ex) {...}
}

核心动作

  1. BeanFactory获取ServletWebServerFactory
  2. 使用 factory.getWebServer() 创建服务器实例
  3. 绑定 server.port 等配置属性
  4. 注册DispatcherServlet (Servlet 环境) 或 WebHandler (响应式环境)
3. finishBeanFactoryInitialization()- 单例初始化扩展
finishBeanFactoryInitialization(beanFactory);

Spring Boot 扩展点:

  • 健康检查系统:HealthEndpointAutoConfiguration
    • **注册 **HealthContributorRegistry
    • 内置磁盘/数据源/JMS 等健康指示器
  • 配置属性绑定ConfigurationPropertiesBindingPostProcessor
    • **处理 **@ConfigurationProperties 注解
    • 将环境属性绑定到 Bean 字段
  • 启动指标:ApplicationStartup 实现
    • 记录 Bean 初始化耗时
    • **跟踪 **@Bean 方法执行
4. finishRefresh() - 生命周期回调
protected void finishRefresh() {// 1. 发布ContextRefreshedEventpublishEvent(new ContextRefreshedEvent(this));// 2. Spring Boot扩展:启动完成处理LiveBeansView.registerApplicationContext(this);
}

7. 刷新后处理

// 扩展点
afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
callRunners(context, applicationArguments);

执行顺序:

  1. 发布ApplicationStartedEvent
  2. 执行ApplicationRunnerCommandLineRunner
    • @Order顺序执行
  3. 发布ApplicationReadyEvent

三、Spring框架集成关键点

  1. 自动配置原理
    • 条件注解:@ConditionalOnClass@ConditionalOnMissingBean
    • 配置类:spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  2. Servlet容器启动
    • ServletWebServerFactoryAutoConfiguration → 创建TomcatServletWebServerFactory
    • DispatcherServletAutoConfiguration → 注册DispatcherServlet
  3. 数据源与事务
    • DataSourceAutoConfiguration → 创建DataSource
    • TransactionAutoConfiguration → 启用@Transactional

四、思维导图总结

版本说明

  • Spring Boot 3.5.0 使用 Spring 6.2.7
  • 自动配置路径:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • 事件驱动模型:ApplicationEvent + ApplicationListener
http://www.lqws.cn/news/591229.html

相关文章:

  • 基于Socketserver+ThreadPoolExecutor+Thread构造的TCP网络实时通信程序
  • 启用不安全的HTTP方法
  • 遥感影像岩性分类:基于CNN与CNN-EL集成学习的深度学习方法
  • 二十八、【环境管理篇】灵活应对:多测试环境配置与切换
  • Prompt生成指南
  • Gin 中间件详解与实践
  • AT6558R-5N32介绍
  • 阿里云-云效自动部署spring boot项目
  • 计算机网络:【socket】【UDP】【地址转换函数】【TCP】
  • 【文件解析】json.load(fp)
  • 借助工具给外语视频加双语字幕的实用指南​
  • 赋能城市安全韧性|众智鸿图总裁扈震受邀出席智慧城市大会发表主题报告
  • 【锂电池剩余寿命预测】GRU门控循环单元锂电池剩余寿命预测(Pytorch完整源码和数据)
  • 【机器学习深度学习】模型微调的基本概念与流程
  • OpenGL 3D编程大师基础之路:从几何体到物理引擎
  • 组合模式在SSO搜索和关键词重叠法中的优化应用
  • 用java,把12.25.pdf从最后一个点分割,得到pdf
  • 大模型及agent开发5 OpenAI Assistant API 进阶应用
  • 浏览器F12开发者工具的使用
  • 隔离网络(JAVA)
  • Ansys Speos | Speos Camera 传感器机器视觉示例
  • iOS 越狱插件 主动调用C函数和OC函数
  • no module named ultralytics
  • Spring Boot WebSocket方案终极指南:Netty与官方Starter对比与实践
  • 【团队开发】git 操作流程
  • Electron 沙箱模式深度解析:构建更安全的桌面应用
  • c++学习(八、函数指针和线程)
  • idea maven自动导包 自动清除无用的依赖包
  • 怎么查看Android设备中安装的某个apk包名和启动页activity
  • 设计模式-模板模式