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 启动失败 发告警邮件、记录错误
相关推荐
St_rive2 小时前
Page Object设计模式
java·开发语言·设计模式
风流 少年2 小时前
Spring AI 2.0:SSE
java·人工智能·spring
凤山老林2 小时前
精细化流量治理:Spring Boot 动态特性开关与灰度发布体系
java·spring boot·后端
用户938515635074 小时前
TypeScript 高级类型 + CSS 三列布局:从类型体操到样式工程的进阶之路
css·面试·typescript
Aphelios3805 小时前
一次锁内网络IO引发的Tomcat线程池“饿死”事故
java·开发语言·spring boot·elasticsearch·tomcat·网络io阻塞·线程池耗尽
不可求~5 小时前
C++ std::string_view 不是字符串:从悬空引用到安全用法
java·开发语言·c++
Lam Tang5 小时前
APS 系列文章10
java·代理模式
考虑考虑6 小时前
Excel导入时产生特殊字符处理
java·后端·java ee
Scabbards_6 小时前
面试Leetcode - Heap 堆
java·leetcode·面试
黄敬峰6 小时前
🐳 Docker 从入门到实战:一次搞定容器化 + Nginx 反向代理
面试