SpringBoot项目启动的过程
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
SpringBoot启动并非简单的main方法执行,而是一套标准化、自动化的容器初始化流程,核心围绕SpringApplication.run()方法展开,全程可分为启动初始化、环境准备、上下文刷新、服务器启动、完成回调五大核心阶段,兼顾依赖注入、自动配置、内置容器启动等核心特性。
第一阶段:启动入口与SpringApplication初始化
所有SpringBoot项目的启动入口,都是标注@SpringBootApplication的主类中的main方法,这是整个流程的起点。
1. 执行主类main方法
开发者编写的启动类代码极简,仅一行启动指令:SpringApplication.run(主类.class, args);,这行代码会触发SpringBoot的底层启动逻辑,完成SpringApplication实例的创建与执行。
2. SpringApplication实例化
run方法内部会先初始化SpringApplication核心对象,完成基础配置加载:
- 推断Web应用类型:根据classpath下的依赖(如Servlet、Reactive包),判断是Servlet Web、Reactive Web还是普通单机应用;
- 加载初始化器(ApplicationContextInitializer):从META-INF/spring.factories或SPI机制,加载全局上下文初始化器;
- 加载监听器(ApplicationListener):扫描并注册项目中的事件监听器,用于监听启动各阶段事件;
- 设置主类源:将启动类作为配置源,后续用于扫描包、加载配置类。
第二阶段:运行准备与环境加载
SpringApplication实例化完成后,进入run方法的执行环节,先完成运行环境的标准化配置,为后续上下文创建打基础。
1. 启动事件广播
发布ApplicationStartingEvent启动事件,所有注册的监听器接收事件并执行预处理逻辑,比如日志初始化、启动banner打印。
2. 环境(Environment)创建与配置
这是SpringBoot“约定大于配置”的核心体现,完成配置文件的加载与解析:
- 创建Environment对象,整合系统变量、JVM参数、配置文件(application.yml/application.properties)、命令行参数;
- 按优先级加载配置:命令行参数 > 外部配置文件 > 内部配置文件 > 默认配置;
- 激活指定环境(如dev/test/prod),解析profile相关配置,最终生成标准化的运行环境。
3. 打印启动Banner与环境校验
加载并打印自定义/默认Banner,同时校验环境配置合法性,发布ApplicationEnvironmentPreparedEvent事件,通知监听器环境已就绪。
第三阶段:应用上下文(ApplicationContext)创建与刷新
这是SpringBoot启动的核心环节,完成IOC容器的创建、Bean的加载与初始化、自动配置生效,对应Spring原生的ApplicationContext刷新流程。
1. 创建ApplicationContext容器
根据第一阶段推断的Web类型,创建对应的上下文对象:
- Servlet Web应用:创建AnnotationConfigServletWebServerApplicationContext;
- Reactive Web应用:创建AnnotationConfigReactiveWebServerApplicationContext;
- 单机应用:创建AnnotationConfigApplicationContext。
2. 上下文预处理
将已加载的Environment绑定到上下文,执行ApplicationContextInitializer初始化器,对上下文做定制化处理;同时将启动类注册为配置类,发布ApplicationContextInitializedEvent事件。
3. 核心:上下文刷新(refresh)
调用Spring原生的refresh()方法,这是IOC容器初始化的核心,包含12个关键步骤,核心动作如下:
- 扫描BeanDefinition:根据启动类的@ComponentScan(@SpringBootApplication内置),扫描指定包下的@Component、@Service、@Controller等注解,注册Bean定义信息;
- 加载自动配置类:通过@EnableAutoConfiguration注解,从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports加载自动配置类,按条件(@Conditional)生效;
- Bean实例化与依赖注入:根据BeanDefinition实例化单例Bean,完成属性填充、依赖注入,执行初始化方法(@PostConstruct、InitializingBean);
- 初始化后置处理器:注册并执行Bean后置处理器,增强Bean功能(如AOP代理、事务管理);
- 初始化生命周期Bean:处理SmartInitializingSingleton等生命周期接口,完成所有单例Bean的初始化。
关键提示:上下文刷新是同步阻塞过程,所有核心Bean、配置、组件均在此阶段完成初始化,刷新失败则项目启动直接终止。
第四阶段:内置Web服务器启动
如果是Web应用,上下文刷新完成后,SpringBoot会自动启动内置服务器(Tomcat/Jetty/Undertow),这是SpringBoot“内嵌容器”的核心特性。
- 根据pom依赖选择服务器:默认依赖spring-boot-starter-web时,启动Tomcat;
- 创建服务器实例,绑定端口、上下文路径等配置,初始化连接器;
- 将SpringMVC的DispatcherServlet注册到服务器,完成Web容器与Spring容器的整合;
- 启动服务器监听端口,等待外部请求接入。
第五阶段:启动完成与回调
服务器启动成功后,SpringBoot进入收尾阶段,发布启动完成事件,执行自定义回调逻辑。
- 发布ApplicationStartedEvent事件,标记项目已启动但未接收请求;
- 执行ApplicationRunner、CommandLineRunner接口的实现类,完成项目启动后的初始化业务(如数据预热、缓存加载);
- 发布ApplicationReadyEvent事件,标记项目完全就绪,可正常处理外部请求;
- 控制台打印启动成功日志,显示端口号、启动耗时等信息,整个启动流程结束。
启动异常终止场景
若流程中任意环节报错,SpringBoot会触发关闭逻辑:
- 发布ApplicationFailedEvent事件;
- 销毁已初始化的Bean、关闭上下文、停止服务器;
- 控制台打印异常堆栈,定位启动失败原因(如端口占用、Bean循环依赖、配置错误)。
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
本专栏聚焦Spring全生态体系,从IoC/AOP核心原理入手,覆盖Spring Boot自动配置、事务管理、Web开发等实战内容。拆解循环依赖、动态代理等高频面试难点,助力开发者从入门到精通,打通单体到微服务的技术链路,解决企业级开发痛点,提升架构设计与问题排查能力,成为Java后端进阶的必备技术专栏。

