SpringBoot启动流程—面试热点

详细分析需看源码

SpringBoot启动流程

SpringBoot启动分为两大步七小步

一,启动准备

  1. 首先SpringBoot会判断当前是web应用还是,响应式应用(Reactive),还是普通应用
  2. 利用SPI机制(ETA-INF/spring.factories),找到所有的初始化器和监听器并待命

二,执行启动

  1. 准备环境:根据你的application.xml配置文件,环境变量,命令行参数等准备环境,组成环境对象
  2. 创建容器:根据第一步确定的类型,创建一个空的SpringIOC容器
  3. 容器刷新:Spring会解析@SpringBootApplication,通过扫描所有Bean,进行自动配置(Web应用内嵌的TomCat在此时启动)
  4. 收尾工作:容器刷新后,发布完成事件,通知所有监视器
  5. 执行回调:检测有无实现CommandLineRunner或ApplicationRunner的Bean,并执行它们的run方法

SPI详解

SPI机制是一种"发现",是运行时多态和反射的体现

有这么一台电脑

SPI前:1接口必须插鼠标USB,2必须键盘

SPI后:1接口被插入USB,检测为键盘,处理键盘输入

代码示例

  1. 定义接口
java 复制代码
package com.example;

public interface Animal {
    void speak();
}
  1. 写入实现类
java 复制代码
// 狗
package com.dog;

public class Dog implements Animal {
    public void speak() {
        System.out.println("汪汪汪");
    }
}
// 猫
package com.cat;

public class Cat implements Animal {
    public void speak() {
        System.out.println("喵喵喵");
    }
}
  1. 创建SPI配置文件resources/META-INF/services/
  • 文件名必须是:接口的全限定名(包含包名)
  • 这里就是:com.example.Animal
  • 文件内容:com.dog.Dog
    com.cat.Cat
  1. 运行发现
java 复制代码
public class Main {
    public static void main(String[] args) {
        // ServiceLoader是Java自带的SPI加载器
        ServiceLoader<Animal> loader = ServiceLoader.load(Animal.class);
        
        // 遍历所有找到的动物
        for (Animal animal : loader) {
            animal.speak();
        }
    }
}
// 输出:
// 汪汪汪
// 喵喵喵

初始化器

初始化器执行时机:容器刷新前,创建容器后

干了啥:

  • 添加自定义环境变量
  • 激活某个 profile(dev/test/prod)
  • 提前注册一些特殊的 Bean

监听器

事件 触发时机 可以干啥
ApplicationStartingEvent 刚点启动,啥都没做 初始化日志系统
ApplicationEnvironmentPreparedEvent 配置文件加载完了 修改环境变量、激活profile
ApplicationContextInitializedEvent 容器刚创建 容器还没开始干活
ApplicationPreparedEvent Bean定义加载完了 可以查看有哪些Bean
ApplicationStartedEvent 容器刷新完成 Runner还没执行
ApplicationReadyEvent 全部搞定 发送通知、打印banner
ApplicationFailedEvent 启动失败 发告警邮件、记录错误
相关推荐
拾-光9 小时前
【Git】命令大全:从入门到高手,100 个最常用命令速查(2026 版)
java·大数据·人工智能·git·python·elasticsearch·设计模式
无人不xiao9 小时前
springBoot 实现 接口进度条
java·spring boot·后端
smileNicky9 小时前
Docker 部署 SpringBoot 项目超详细教程
spring boot·docker·容器
pkowner9 小时前
若依分页问题及解决方法
java·前端·算法
largecode10 小时前
如何让电话显示店名?来电显示店铺名称,提升有效接通率
java·开发语言·spring·百度·学习方法·业界资讯·twitter
xuhaoyu_cpp_java10 小时前
SpringMVC学习(五)
java·开发语言·经验分享·笔记·学习·spring
计算机安禾10 小时前
【c++面向对象编程】第22篇:输入输出运算符重载:<< 与 >> 的友元实现
java·前端·c++
HLAIA光子10 小时前
这些Spring Boot写法已经过时了!
spring boot·后端
旷世奇才李先生10 小时前
Java虚拟线程原理与实践
java
heimeiyingwang10 小时前
【架构实战】RPC框架Dubbo3.0:高性能Java通信之道
java·rpc·架构