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 启动失败 发告警邮件、记录错误
相关推荐
葫芦和十三10 小时前
图解 MongoDB 17|大集合与工作集:数据超过内存怎么办
后端·mongodb·面试
葫芦和十三18 小时前
图解 MongoDB 18|复制集拓扑:Primary、Secondary 和 Arbiter 的分工
后端·mongodb·面试
狼爷1 天前
吃透 Java Function 接口,搞定 99% 的 Stream 场景
java·函数式编程
葫芦和十三1 天前
图解 MongoDB 15|journal 与持久化:写入怎么不丢,崩溃怎么恢复
后端·mongodb·面试
葫芦和十三1 天前
图解 MongoDB 16|压缩:snappy、zstd 和 zlib 的取舍
后端·mongodb·面试
祎雪双十Gy1 天前
从 DataX 的配置加载说起:我用 FastJson2 做了一个轻量级动态配置管理库
java·后端
labixiong1 天前
实现一个能跑的迷你版Promise(一)
前端·javascript·面试
小锋java12341 天前
分享一套锋哥原创的SpringBoot4+Vue3宠物领养网站系统
java
考虑考虑1 天前
Java实现hmacsha1加密算法
java·后端·java ee
掉鱼的猫1 天前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·spring boot