springboot启动流程
整体一句话概括:执行 SpringApplication.run(启动类.class, args) 分两大阶段——
准备阶段:创建 SpringApplication 对象,预加载环境、推断项目类型、加载自动配置类;
运行阶段:创建容器、加载配置、扫描 Bean、启动内置 Tomcat,对外提供接口。
一、第一步:new SpringApplication() 实例化对象,做 3 件事
1. 记录主启动类
把我们写的 HospitalManagerApplication 存起来,后续扫描以此为根包。
2. 推断应用类型
看项目有没有 Tomcat 依赖 → 判定为 Web 应用(会创建内嵌 Tomcat 容器);
无 Web 依赖就是普通 Java 程序。
3. 加载 SPI 自动配置类
读取 META-INF/spring.factories 文件,提前加载所有场景自动配置类(MyBatis、Redis、Web、Tomcat 等),这就是 Spring Boot 自动配置的核心来源。
二、第二步:调用 run() 核心方法(启动全过程)
1. 开启启动计时器,打印 Banner
就是启动时控制台那个 Spring 图案,可自定义关闭。
2. 创建并准备运行环境 Environment
加载所有配置:yml、properties、命令行参数、系统环境变量;
区分多环境 dev/prod,把配置统一封装,后面容器直接读取;
校验配置是否合法,端口、数据库地址等配置错误这里提前抛异常。
3. 创建 Spring IOC 容器(ApplicationContext)
根据前面推断的 Web 类型,创建 AnnotationConfigServletWebServerApplicationContext 容器,所有对象都存在这个容器里。
4. 准备容器上下文:加载主启动类配置
把我们的启动类 HospitalManagerApplication 作为配置类注册进容器,@SpringBootApplication 复合注解开始生效:
@ComponentScan:扫描启动类同包及子包下所有加了 @Controller / @Service / @Mapper / @Component 的类,标记为 Bean;
@EnableAutoConfiguration:拿出第一步加载的 spring.factories 自动配置类,根据项目依赖按需创建组件:
引入 MyBatis-Plus 依赖 → 自动创建数据源、SqlSession、Mapper 代理对象;
引入 Redis 依赖 → 自动创建 RedisTemplate;
@Configuration:启动类本身也能写 @Bean 方法注册自定义对象。
5. @MapperScan 生效
@MapperScan("com.bear.hospital.mapper") 单独扫描 mapper 包,自动给所有 Mapper 接口生成代理实现类,注入容器,Service 才能直接 @Autowired 注入 Mapper 操作数据库。
6. 刷新容器 refresh()(最核心步骤)
这是 Spring 原生核心方法,内部流程:
扫描所有 Bean 定义(Controller、Service、Mapper、配置类);
实例化单例 Bean,完成依赖注入(@Autowired 自动赋值);
执行 AOP 动态代理、事务管理、拦截器、全局异常处理器初始化;
初始化第三方组件:Redis 连接池、数据库连接池、OSS 工具等。
7. 创建内置 Web 服务器(Tomcat/Jetty)
容器刷新完成后,检测是 Web 项目,自动创建 Tomcat,绑定 yml 配置的端口(默认 8080)。
8. 启动 Tomcat,绑定 Spring 容器
Tomcat 启动,把 Spring 容器交给 Tomcat 管理,监听浏览器/前端发来的 HTTP 请求,请求进来会分发到对应 Controller 接口。
9. 执行所有 ApplicationRunner / CommandRunner
项目启动完成后执行自定义后置任务,比如初始化缓存、加载字典数据。
10. 启动完成,打印日志,服务运行中
控制台输出启动耗时、访问地址,服务常驻运行,等待请求。