Spring Boot知识总结

一、Spring Boot核心定位

简化 Spring 开发,自动配置、内嵌服务器、Starter 依赖、生产级特性,约定大于配置。

二、Spring Boot核心知识

1. 启动流程(精简版)

Spring Boot 启动 = 准备环境 + 刷新容器 + 初始化组件 + 启动服务器

最核心步骤只有一个:refresh () 刷新容器(IoC、Bean、自动配置、AOP 全在这里)

具体启动流程:

(1) 执行启动类 main 方法,调用 SpringApplication.run()

(2) 构造 SpringApplication,判断 Web 类型,加载监听器与初始化器;

(3) 准备运行环境,加载配置文件、命令行参数;

(4) 创建并刷新 ApplicationContext 容器

resh() :扫描、创建、初始化 Bean,完成自动配置、AOP、事务;

(5) 启动内嵌 Tomcat/Undertow 服务器;

(6) 发布启动事件,应用就绪。

2. 自动配置原理

(1) 核心注解

@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan

(2) 自动配置流程

@EnableAutoConfiguration 开启自动配置

读取SPI文件:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

加载所有自动配置类

按条件注解判断是否生效

  • @ConditionalOnClass:存在某个类
  • @ConditionalOnBean:存在某个 Bean
  • @ConditionalOnMissingBean:不存在才创建
  • @ConditionalOnProperty:配置项满足

满足条件则创建 Bean

3. 配置加载优先级

(1) 配置文件

  • application.yml / application.properties
  • 多环境:application-dev.ymltestprod

(2) 配置加载优先级

命令行参数 > 外部配置文件 > application.yml > bootstrap.yml(Cloud 专用)

(3) 配置绑定

  • @Value:直接取值
  • @ConfigurationProperties:批量绑定前缀

4. SPI(Service Provider Interface,服务发现)机制

(1) SPI的核心作用
  • 解耦 :不用硬编码 new 实现类
  • 可插拔:替换实现类只改配置,不改代码
  • SpringBoot 自动配置底层就是 SPI
(2) Java 原生SPI

规则

  • 接口:com.xxx.service.MyService
  • 实现:com.xxx.service.impl.MyServiceImpl
  • 配置文件路径(固定):META-INF/services/接口全限定名

使用方式

java 复制代码
ServiceLoader<MyService> loader = ServiceLoader.load(MyService.class);
for (MyService service : loader) {
    service.doSomething();
}

缺点

  • 一次性加载所有实现类(浪费资源)
  • 不能按需获取
  • 不支持排序、条件、过滤
(3) Spring SPI 机制(SpringBoot 自动配置核心)

Spring 专用 SPI 路径

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

作用

SpringBoot 启动时自动读取这个文件,加载里面的自动配置类 。这就是 @EnableAutoConfiguration 底层原理

Spring SPI 优势

按需加载、支持条件注解 @Conditional、支持排序、自动装配

除了 Spring Boot,还有哪些框架用 SPI?

凡是要做到可插拔、可扩展、自动加载的框架,几乎都用 SPI。例如:

  • JDBC:加载数据库驱动;
  • Dubbo:协议、负载均衡、序列化,自己增强了 SPI;
  • MyBatis / MyBatis-Plus:插件、方言自动加载;
  • Slf4j:发现日志实现;
  • ShardingSphere、Seata、Sentinel 等分布式框架也大量使用

5. 常用的Starter

  • spring-boot-starter-web:Web 开发
  • spring-boot-starter-data-redis:Redis
  • spring-boot-starter-jdbc / mybatis:数据库
  • spring-boot-starter-security:权限
  • spring-boot-starter-actuator:监控

三、拓展知识

1. 自定义Spring Boot Starter并按需使用

(1) 命名用 xxx-spring-boot-starter 规范;

(2) 创建属性类 @ConfigurationProperties 绑定配置;

(3) 编写自动配置类,用 @Configuration + 条件注解类,并为@Bean定义业务类;

java 复制代码
@Configuration
@ConditionalOnClass(SmsService.class) // 1. 有这个类才生效
@EnableConfigurationProperties(SmsProperties.class)
// 2. 配置文件开启才生效(核心按需开关)
@ConditionalOnProperty(prefix = "sms", name = "enabled", havingValue = "true")
public class SmsAutoConfiguration {

    @Bean
    // 3. 容器里没有才创建(允许用户自定义覆盖)
    @ConditionalOnMissingBean
    public SmsService smsService(SmsProperties properties) {
        return new SmsService(properties);
    }
}

(4) 在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 注册配置类;

(5) 打包后其他项目引入依赖即可自动生效。

  • 开启加载(默认)
java 复制代码
sms:
  enabled: true  # 满足条件 → 自动创建 SmsService Bean
  appId: 123
  secret: abc
  • 关闭加载(不加载 Bean)
java 复制代码
sms:
  enabled: false # 不满足条件 → 跳过,不加载

2. 减少Bean加载时间

Spring Boot 启动慢,90% 是 Bean 加载 / 实例化 / 初始化太慢 。减少Bean加载时间的整体思路是少加载、晚加载、异步加载、不加载无用 Bean。具体可以通过以下方式减少Bean的加载时间:

  • 开启懒加载(最简单、最有效),用到时再初始化 Bean;
java 复制代码
spring:
  main:
    lazy-initialization: true
  • 排除不需要的自动配置,减少无用 Bean 加载,不加载数据库、消息队列等无用自动配置;
java 复制代码
spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
      - org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
  • 缩小包扫描范围,不扫描无关包,只扫需要的包,跳过无用包、第三方包、测试包;
java 复制代码
@ComponentScan(basePackages = "com.xxx.controller, com.xxx.service")
  • 关闭循环引用(SpringBoot 2.7+),减少依赖检查耗时;
java 复制代码
spring:
  main:
    allow-circular-references: false
  • 异步初始化 Bean(高级优化),不阻塞主线程;
java 复制代码
@Bean
@Async
public UserService userService() {
    return new UserServiceImpl();
}
  • 依赖优化,删除无用 Starter、排除无用 Jar、避免重复依赖
  • 使用Spring Boot 加速工具 / 框架扩展
    • ​​​​​Spring Boot Daemon 进程预热
    • 阿里 Arthas 优化
    • 云原生,如镜像预热、JVM 预热

3. 启动优化

  • 开启全局懒加载,用到时再初始化 Bean;
  • 排除不需要的自动配置,减少无用 Bean 加载;
  • 缩小包扫描范围,避免全量扫描;
  • 关闭循环依赖,减少依赖检查耗时;
  • 慢初始化 Bean 异步化,不阻塞主线程;
  • 替换为性能更高的 Undertow 容器;
  • 裁剪依赖、禁用 JMX、关闭无用监控;
  • 高阶方案:分层启动、进程预热、GraalVM 原生镜像

4. 定位哪个 Bean 初始化最慢(Actuator / 启动日志分析)

开启启动分析报告:

复制代码
logging:
  level:
    org.springframework.context.annotation: DEBUG

或使用:

  • Spring Boot Actuator
  • StartupEndpoint
  • Arthas 分析方法耗时

5. 启动链路分析

启动链分析 = 追踪 Spring Boot 从 run () 到服务启动全过程的耗时与步骤 目的:定位慢 Bean、慢配置、慢初始化、阻塞点,精准优化启动速度。

(1) 4 种最实用的启动链分析方法
a、开启spring.main.log-startup-info 打印启动耗时报告(最简单,零侵入):打印所有 Bean 初始化耗时排序
复制代码
spring:
  main:
    log-startup-info: true  # 打印启动信息
logging:
  level:
    # 开启启动耗时统计(关键!)
    org.springframework.boot.StartupInfoLogger: INFO
    org.springframework.context: DEBUG

打印效果

  • 列出初始化最慢的 Bean
  • 显示每个 Bean 构造、依赖注入、初始化耗时
  • 直接定位慢 Bean
b、使用 Actuator 端点(最专业,可视化),查看完整启动时间线与阶段耗时

步骤①:引入 Actuator

XML 复制代码
​​​​​​​<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-actuator</artifactId> 
</dependency>

步骤②:开启配置

XML 复制代码
management:
  endpoints:
    web:
      exposure:
        include: startup
  endpoint:
    startup:
      enabled: true

步骤③:访问查看完整启动时间线

如:http://localhost:port/actuator/startup

能看到

  • 启动阶段耗时(refresh、onRefresh、createBean...)
  • 每个 Bean 生命周期时间
  • 精准定位阻塞步骤
c、使用 JVM 调试 / Arthas 追踪(生产环境神器)

①启动时打印堆栈:java -jar app.jar --debug

②Arthas 追踪启动方法:

bash命令 trace org.springframework.context.support.AbstractApplicationContext refresh

d、 启动日志关键阶段拆分,重点排查 refreshContext 阶段

Spring 启动核心流程 = 5 个阶段:

prepareEnvironment:配置加载

prepareContext:上下文准备

③ refreshContext(最核心):Bean 加载、自动配置

④ onRefresh:内嵌容器启动

⑤ finishRefresh:完成启动

90% 慢启动都卡在 refreshContext

e、定位慢 Bean、慢配置、阻塞初始化后针对性优化
(2) 启动链分析能定位哪些问题
  • 哪个 Bean 初始化最慢(连接池、第三方 SDK、Feign 等)
  • 自动配置加载过多
  • 循环依赖导致耗时高
  • Bean 依赖过深、层级复杂
  • @PostConstruct 里执行慢逻辑
  • MyBatis、Redis、MQ 启动时建立连接阻塞
相关推荐
智驭未来掌门人5 小时前
利用FFmpeg快速实现一个RTSP推流服务器
后端
垚垚学技术_聚焦云原生6 小时前
K8s Pod 完整生命周期详解
后端
JavaGuide6 小时前
Github 史诗级故障,与此同时,Cursor 版「GitHub」正式上线!
前端·后端
不一样的少年_6 小时前
修了 Bug、做了重构,为什么老板还是觉得你没产出?
前端·后端·程序员
水深火乐6 小时前
安全地生成验证码、密码和 Token
后端
小强19886 小时前
SQL Server 慢查询怎么定位?一套从“卡”到“快”的完整排查流程
后端
水深火乐6 小时前
interface和any
后端
步行cgn6 小时前
MyBatis Error evaluating expression ‘ids‘. Return value (3) was not iterable 错误详
java·后端
神奇小汤圆6 小时前
Spring Boot + LangChain4j实现RAG——从零搭建企业级知识库问答系统
后端
H_Peak6 小时前
Python运算符与流程控制:if条件判断
后端