Spring Boot 启动流程详解(源码级分析)
🚀 Spring Boot 启动流程详解(源码级分析)
📌 一、问题背景
在传统Spring项目中,需要大量XML配置、Servlet注册以及各种初始化工作,而Spring Boot通过一个简单的main方法即可完成整个应用启动。
看似只有一行代码,实际上Spring Boot内部完成了数百个类之间的协同工作,最终构建出完整的IOC容器并启动Web服务器。
SpringApplication.run()内部到底做了哪些事情?Bean是什么时候创建的?自动装配什么时候发生?Tomcat又是什么时候启动的?
🎯 二、核心原理
Spring Boot启动的本质,就是创建Spring IOC容器,并在容器初始化过程中完成Bean注册、自动配置、依赖注入以及Web服务器启动。
整个启动过程可以分为九个核心阶段:
- 创建SpringApplication对象
- 推断应用类型
- 加载ApplicationContext
- 准备Environment环境
- 创建IOC容器
- 执行BeanFactoryPostProcessor
- 实例化所有Bean
- 启动内嵌Tomcat
- 执行Runner回调,启动完成
Spring Boot启动流程本质就是:创建SpringApplication → 创建IOC容器 → 加载Bean → 自动装配 → 启动Tomcat → 对外提供服务。
📊 三、数据结构分析
SpringApplication负责整个启动流程,而真正存放Bean的是BeanFactory。BeanDefinition保存Bean的元数据,真正实例化完成后才会变成Bean对象。
🔥 四、算法分析
SpringApplication.run()可以抽象为下面几个步骤:
真正最重要的方法其实只有一个,那就是refresh()。
Spring Boot启动流程,其实80%的工作都是在AbstractApplicationContext.refresh()里面完成的。
🚀 五、执行流程
💡 六、实际案例
案例一:SpringApplication.run()
进入run方法后,首先创建SpringApplication对象,并推断当前应用属于Servlet、Reactive还是普通Java程序。
案例二:refresh()刷新容器
refresh()是整个Spring生命周期的核心,它负责BeanDefinition加载、Bean后处理器注册、Bean实例化以及容器最终初始化。
案例三:Bean创建流程
Tomcat启动并不是SpringApplication.run()开始时就启动,而是在refresh()阶段的onRefresh()过程中启动内嵌Web服务器,之后才开始监听HTTP请求。
✅ 七、优缺点分析
| 优点 | 说明 |
|---|---|
| 自动配置 | 减少大量XML配置,提高开发效率 |
| 内嵌Web服务器 | 无需部署WAR即可运行 |
| IOC生命周期完善 | 统一管理Bean生命周期和依赖关系 |
| 扩展能力强 | 支持Starter、自动装配、监听器、事件机制等 |
🎯 八、面试常见问题
main方法中的SpringApplication.run()就是整个Spring Boot应用的启动入口。
AbstractApplicationContext.refresh()。IOC容器创建、Bean实例化、自动装配以及Tomcat启动几乎都围绕refresh()展开。
BeanDefinition加载完成后,在refresh()的finishBeanFactoryInitialization()阶段实例化所有非懒加载单例Bean。
Tomcat并不是main方法启动时立即启动,而是在refresh()过程中调用onRefresh()创建并启动内嵌Tomcat,随后开始监听HTTP端口。
自动装配依赖@EnableAutoConfiguration加载AutoConfiguration配置类,在refresh()过程中注册BeanDefinition,并最终完成Bean实例化和依赖注入。
📌 九、总结
Spring Boot启动流程可以浓缩为下面九个步骤:
对于高级开发者而言,需要重点掌握SpringApplication.run()、ApplicationContext创建、refresh()生命周期、Bean实例化、自动装配原理以及Tomcat启动时机。其中,refresh()方法是整个Spring Boot启动流程的核心,也是阅读Spring源码和面试时最值得深入理解的部分。
相关文章
-
死锁详细介绍
死锁是指两个或多个线程互相等待对方占用的资源,而永远无法继续执行下去的情形。
NEW个对象 2025-01-10
-
支付中心:调用第三方支付,第三方已经处理成功,但是调用方显示支付失败,是什么原因造成的?
先说下支付流程: 支付中心调用第三方,第三方将支付结果通过异步的方式返回给支付中心,支付中心做后续的处理。 从流程中来看:
NEW个对象 2024-10-28
-
RAG可观测性主要分三个层次
RAG可观测性主要分三个层次
NEW个对象 2026-07-27