面试官逼问 SpringBoot 启动原理?这篇源码级解析让你对答如流
🚀 SpringBoot 启动流程全解析(含源码入口)
你是否也用过
@SpringBootApplication
一键启动,却从没真正想过:
- SpringBoot 到底启动了什么?
- 谁加载了配置文件?
- Bean 是什么时候创建的?
本篇我们一次性讲清 SpringBoot 启动全过程,配源码入口、关键类图、真实应用语境,建议收藏!
🧠 一、SpringBoot 应用启动的主流程
看起来我们只是写了一个 main()
方法:
@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}
但这一行,其实背后干了大量的事情!
🧭 二、SpringApplication.run() 都做了什么?
我们点进去源码可以看到:
public ConfigurableApplicationContext run(String... args) { ... prepareEnvironment() prepareContext() refreshContext() afterRefresh() ...}
👣 详细流程如下:
new SpringApplication()
prepareEnvironment()
prepareContext()
load()
refreshContext()
afterRefresh()
🔍 三、源码入口类解析(重要类图)
SpringBoot 启动过程中涉及几个重要的类:
🧩 1. SpringApplication
最核心的类,负责整个启动流程管理。
SpringApplication app = new SpringApplication(MyApp.class);
构造函数中会做几件事:
- 判断是否是 Web 应用(Servlet or Reactive)
- 加载 ApplicationContext 类型(默认是 AnnotationConfigApplicationContext)
- 加载初始化器、监听器(通过 SpringFactoriesLoader)
🧩 2. ApplicationContext
Spring 的 IOC 容器,所有 Bean 的诞生地。
SpringBoot 默认用的是:
AnnotationConfigServletWebServerApplicationContext
它是 GenericApplicationContext
的子类,支持注解扫描、Web 环境。
🧩 3. Environment
管理配置的统一入口,核心是:
application.yml
系统环境变量
命令行参数
这些配置都会被封装进 ConfigurableEnvironment
中,供后续使用。
🧩 4. BeanDefinitionLoader
负责将 @ComponentScan
、@Bean
、@Configuration
等定义解析为 BeanDefinition。
即:把类变成容器能理解的结构
⚙️ 四、从配置文件到 Bean 的生命周期(串起来)
来看一张简图:
application.yml ↓Environment(封装配置) ↓BeanFactoryPostProcessor / PropertySourcesPlaceholderConfigurer ↓@Value、@ConfigurationProperties 生效 ↓Bean 实例化 + 属性注入
也就是说,配置文件的加载早于 Bean 的创建,只有环境准备好,Spring 才能把配置注入进去。
⛳ 五、开发者可插入的扩展点(重要)
SpringBoot 留了非常多的扩展点,以下几个在实际项目中非常常用:
ApplicationRunner
/ CommandLineRunner
ApplicationContextInitializer
EnvironmentPostProcessor
ApplicationListener
🧱 六、SpringBoot 启动流程完整时序图
main() ↓new SpringApplication() ↓run() ├─ prepareEnvironment() ├─ prepareContext() ├─ refreshContext() └─ afterRefresh()
🧪 七、真实项目中的启动流程调试建议
- 打断点调试:在
SpringApplication.run()
内部打断点 - 加监听器输出顺序:实现
ApplicationListener
观察事件触发 - 观察 Bean 初始化日志:设置日志级别为 DEBUG
logging.level.org.springframework=DEBUG
✅ 八、总结:SpringBoot 启动背后的真相
📌 九、面试延伸题
💬 “SpringBoot 如何加载 application.yml 的?”
答:通过 StandardEnvironment
+ ConfigFileApplicationListener
监听加载。
💬 “@ComponentScan 的扫描入口在哪里?”
答:在 SpringApplication.run()
中,通过 AnnotatedBeanDefinitionReader
加载主类,再通过 ClassPathBeanDefinitionScanner
扫描组件。
💬 最后
这是一篇适合收藏和反复阅读的文章,
它不仅能让你理解 SpringBoot 启动的底层流程,
更能让你在面试或项目中说出“why not just magic”。
欢迎点赞 ⭐ 收藏 📌 留言 💬
每天一篇,继续更新!