news 2026/5/11 14:56:58

《Spring核心机制》第六篇:一篇读懂SPI

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《Spring核心机制》第六篇:一篇读懂SPI

《Spring核心机制》第六篇:一篇读懂 SPI

在 Spring 生态中,经常听到一句话:

“Spring 之所以强大,很大程度上是因为它把扩展点做得非常彻底,而这些扩展点绝大多数都是通过SPI机制来实现的。”

今天我们就来彻底搞清楚:Spring 到底是怎么玩 SPI 的?

1. 什么是 Java SPI?(基础回顾)

Java SPI 全称:Service Provider Interface
核心思想一句话总结:

“接口定义在核心包里,实现类写在第三方 jar 包里,通过配置文件让系统自动发现并加载这些实现。”

经典的配置文件位置(JDK 标准):

META-INF/services/接口全限定名

文件内容示例(一行一个实现类全限定名):

com.mysql.cj.jdbc.Driver org.postgresql.Driver

JDK 加载方式:

ServiceLoader.load(Driver.class).forEach(driver->System.out.println(driver.getClass().getName()));

2. Spring 是怎么“玩坏”Java SPI 的?

Spring 并没有完全沿用 JDK 原生的ServiceLoader,而是自己实现了一套更强大、更灵活的Spring Factories 机制(也被称为 Spring SPI)。

最核心的区别对比

特性JDK 原生 SPI (ServiceLoader)Spring Factories (Spring SPI)谁更强?
配置文件位置META-INF/services/META-INF/spring.factoriesSpring
配置文件格式纯文本,一行一个实现类Properties 格式,支持 key=valueSpring
一个接口允许多个实现是,且更友好(可以按 key 分类)Spring
支持按 key 分组不支持支持(同一个文件里可以定义很多不同种类的 SPI)Spring 大胜
支持排序/优先级不支持(加载顺序不确定)支持 @Order / Ordered 接口Spring
支持条件装配不支持支持 @Conditional 等条件注解Spring
懒加载部分支持(迭代时才加载)支持延迟加载(Spring Boot 更进一步)Spring Boot
循环依赖/重复加载问题容易出现问题框架层面做了大量优化与保护Spring
当前主流使用量JDBC、JDBC驱动、日志框架等Spring 全家桶几乎全部依赖它Spring 完胜

3. Spring Boot 中最常见的 spring.factories 内容示例

# 核心配置类加载器(最重要的一行,几乎所有 Spring Boot 项目都会用到) org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ ... # Application Context Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Application Listeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer # 模板解析器(Thymeleaf、FreeMarker 等) org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ ... # 嵌入式容器工厂 org.springframework.boot.web.embedded.EmbeddedWebServerFactoryCustomizer=\ ...

一句话总结 spring.factories 的地位:

它就是 Spring Boot 自动配置的“大脑”和“插件注册表”

4. Spring SPI 的几种典型使用场景对比

使用场景典型 key(接口)典型实现类举例加载时机
自动配置EnableAutoConfigurationxxxAutoConfiguration容器启动早期
初始化器ApplicationContextInitializerConfigDataApplicationContextInitializer非常早期
监听器ApplicationListenerLoggingApplicationListener容器生命周期各个阶段
BeanFactoryPostProcessorBeanFactoryPostProcessorPropertySourcesPlaceholderConfigurerBean 定义阶段
BeanPostProcessorBeanPostProcessorAutowiredAnnotationBeanPostProcessorBean 初始化前后
嵌入式容器自定义WebServerFactoryCustomizerTomcatServletWebServerFactoryCustomizerWeb 容器启动时
自定义 HealthIndicatorHealthIndicatorDiskSpaceHealthIndicatorActuator 健康检查时

5. 面试/实战最常被问的几个 SPI 相关问题

Q1:Spring Boot 是怎么做到“引入一个 starter 就自动配置”的?

A:靠的就是spring.factories中的EnableAutoConfiguration那一行。
Spring Boot 启动时会读取所有 jar 包里的 spring.factories,把所有自动配置类收集起来,然后根据@Conditional条件决定哪些生效。

Q2:为什么不直接用 JDK SPI?

A:

  1. JDK SPI 不支持分组(所有实现都一股脑加载)
  2. 没有优先级控制
  3. 没有条件加载能力
  4. 加载时机和方式不够灵活

Q3:如果我自己写一个 starter,应该怎么定义 SPI?

最常见的三种方式(推荐顺序):

# 方式1:最推荐(自动配置) org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.yourcompany.yourstarter.YourAutoConfiguration # 方式2:自定义初始化器(极早期介入) org.springframework.context.ApplicationContextInitializer=\ com.yourcompany.yourstarter.YourInitializer # 方式3:自定义监听器 org.springframework.context.ApplicationListener=\ com.yourcompany.yourstarter.YourListener

6. 2025-2026 年的新趋势(小彩蛋)

  • Spring Boot 3.x + GraalVM:很多自动配置类开始使用@NativeHint来配合原生编译
  • 模块化 starter:越来越多的 starter 采用“分层 SPI”设计(核心 + 可选扩展)
  • 函数式 + SPI:Spring Boot 3.x 中大量使用函数式 Bean 定义,也会结合 spring.factories 注册
  • eBPF + Spring:部分云原生场景开始通过 eBPF 动态注册/替换 Spring 的 SPI 实现(实验阶段)

一句话总结本篇核心认知

Spring 之所以能做到“高度可扩展却又使用简单”,最核心的秘密武器之一,就是它把 Java SPI 升级成了功能强大、分类清晰、条件丰富、优先级可控的 Spring Factories 机制。

下一期想看什么?

  • Spring 的 @Conditional 家族全家桶深度解析
  • EnableAutoConfiguration 背后的加载原理与源码流程
  • 如何优雅地自定义一个高质量 Spring Boot Starter(包含 SPI 实践)
  • Spring Factories 与 JDK SPI、Dubbo SPI、OSGi 的终极对比

告诉我你的选择~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 19:52:48

强烈安利8个AI论文工具,继续教育学生轻松搞定论文写作!

强烈安利8个AI论文工具,继续教育学生轻松搞定论文写作! AI 工具如何改变论文写作的未来 在当前的学术环境中,越来越多的继续教育学生面临论文写作的压力。无论是撰写开题报告、撰写初稿,还是进行查重和降重,每一步都可…

作者头像 李华
网站建设 2026/5/5 17:24:28

VP引导定位软件-定位纠偏(不带角度)

VP引导定位软件-定位纠偏(不带角度)// 定位模式if(GlobalParamters.SoftModel1){// 一 获取圆的中心AlgorithmService.Instance.DetectCircle(info.Image, out double ImageX, out double ImageY);// 二 获取目标位置TargetLoaction targetLoaction (Ta…

作者头像 李华
网站建设 2026/5/7 5:00:37

基于SpringBoot的房屋交易平台的设计与实现(11712)

有需要的同学,源代码和配套文档领取,加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码(前后端源代码SQL脚本)配套文档(LWPPT开题报告)远程调试控屏包运行 三、技术介绍 Java…

作者头像 李华
网站建设 2026/5/1 0:44:37

基于MATLAB的IIR FIR滤波器的设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于MATLAB的IIR FIR滤波器的设计(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 以及音频去噪功能的实现,包括对滤波器函数进行时频域分析,对音频进行加高频噪声或高斯噪声,对加噪音频进行…

作者头像 李华
网站建设 2026/5/8 5:39:12

流水线调度柔性作业车间调度(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

流水线调度 柔性作业车间调度 内容: 提供各类调度问题解决方案,包括作业车间调度JSP、柔性作业车间调度 FJSP、流水车间调度FSP、混合流水车间调度HFSP、多目标优化、动态调度、蒙特卡洛模拟、机器分配与序列排序等 算法库齐全,遗传算法、蚁群…

作者头像 李华
网站建设 2026/5/9 3:30:25

软件测试技术报告(源码+测试报告)(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

软件测试技术报告(源码测试报告)(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 项目名:旅游景点推荐平台( web) 测试需求分析详细、测试用例设计多样、涉及黑盒测试…

作者头像 李华