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 启动失败 发告警邮件、记录错误
相关推荐
东离与糖宝几秒前
OpenClaw 企业级实战:Java 微服务集成 AI 智能体,自动处理业务流
java·人工智能
半瓶榴莲奶^_^5 分钟前
优先级队列(堆)
java·数据结构·算法
东离与糖宝5 分钟前
成本砍半!Java 生产环境 INT4/INT8 模型量化 + 提示词缓存落地
java·人工智能
Lyyaoo.6 分钟前
Spring中Bean的作用域与生命周期
java·后端·spring
遇见你...6 分钟前
B03 SpringMVC拦截器
java·开发语言
星晨雪海6 分钟前
缓存更新操作实例
java·spring·缓存
東雪木10 分钟前
Java学习——接口 (interface) 与抽象类 (abstract) 的本质区别、选型标准
java·开发语言·jvm·学习·java面试
_MyFavorite_11 分钟前
JAVA重点基础、进阶知识及易错点总结(16)多线程基础(Thread & Runnable)
java·开发语言
大数据新鸟16 分钟前
java8基础知识--字符串
java
ChoSeitaku17 分钟前
NO.2|数据结构设计|日志封装|DeepSeel接入封装|全量返回实现测试|SSE|流式响应实现测试
java·jvm·数据结构