《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 的终极对比

告诉我你的选择~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1170030.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ACP:1.让 AI 工具配置与能力管理,真正走向体系化

ACP:让 AI 工具配置与能力管理,真正走向体系化 如果你已经把 AI 编程工具当成了日常生产力的一部分,那么你大概率遇到过这样一种情况:这个项目里,Agent 角色是为某个工具单独调的 Prompt 模板在不同 IDE 之间来回…

【图像融合】基于matlab高分辨率全色图IHS图像融合(含评价指标)【含Matlab源码 14959期】

💥💥💥💥💥💥💞💞💞💞💞💞💞💞欢迎来到海神之光博客之家💞💞💞&#x1f49…

时间序列因果推断:顶会发文的 “黄金赛道”,新手也能上手

时间序列因果推断是当前机器学习与统计学交叉领域的热点方向,在 ICML、NeurIPS、ICLR、KDD、AAAI 等顶会中发文量持续攀升,对新手友好且创新空间大,整体属于 “好发论文” 的领域,核心原因如下:一、为什么 “好发”&am…

测试用例管理怎么做度量?6个指标思路和工具对比

本文将深入对比6款测试用例管理工具:PingCode、Worktile、Tricentis qTest、Azure DevOps Test Plans、Zephyr Scale、Xray。一、测试用例管理为什么会变成“质量瓶颈”很多团队的测试用例管理,最初看起来都不难:几份文档、一个表格&#xff…

深入了解 Python 中的 Scrapy:强大的网络爬虫框架

什么是 Scrapy? Scrapy 是一个基于 Python 的高级网络爬虫框架,专门用于从网页中抓取数据(也称为“网络抓取”或“网页采集”)。它最初由 Scrapinghub 公司开发并开源,现已成为 Python 社区中最广泛使用的爬虫框架之一…

【图像融合】高分辨率全色图IHS图像融合(含评价指标)【含Matlab源码 14959期】

💥💥💥💥💥💥💥💥💞💞💞💞💞💞💞💞💞Matlab武动乾坤博客之家💞…

产品方案评审前一晚,我让AI先帮我当了一次“领导”

引言产品方案已经写完了,但到了评审前一晚,很多产品经理还是会下意识地再打开一遍文档看看。不是怕讲不清楚,而是总觉得会有没考虑周全的地方。不知道方案会被从哪个角度质疑?会不会有一个关键问题,曾经完全没想到&…

【Linux】五种IO模型与非阻塞IO

Linux 五种 IO 模型 非阻塞 IO 的完整梳理 (2025-2026 面试/实战最常考版本) Linux 下最经典的五种 IO 模型,几乎是所有中高级后端/网络编程面试必问内容。 序号IO 模型名称阻塞阶段进程在内核等待数据时是否阻塞?进程在数据从…

救命神器!8款AI论文软件测评:本科生毕业论文痛点全解决

救命神器!8款AI论文软件测评:本科生毕业论文痛点全解决 2026年AI论文工具测评:为何需要这份榜单? 随着人工智能技术的不断进步,越来越多的本科生开始依赖AI论文工具来提升写作效率和论文质量。然而,面对市场…

多模融合时代,文档数据库正在被重新定义——金仓数据库如何构建新一代文档数据底座

目录 性能对标主流:不只是可用,更要好用 对比 Oracle:文档能力同样具备竞争力 内核融合:多模能力不是“拼装”,而是原生一体 1. 企业级一致性与可靠性原生继承 2. 统一查询优化与索引体系 3. 真正的“多模一体”…

进程间通信(IPC)完全指南:原理、实现与最佳实践

进程间通信(IPC)完全指南:原理、实现与最佳实践 在2026年的操作系统与分布式系统中,进程间通信(IPC) 仍是核心机制,尤其在多核、多进程环境、多容器化(如Docker/Kubernetes&#xf…

2026国内最新爆款裤料品牌top5推荐!广东广州等地优质裤料供应商权威榜单发布,创新工艺与品质保障助力服饰产业升级 - 品牌推荐2026

2026最新爆款裤料推荐!国内优质裤料供应商权威榜单发布,创新工艺与品质保障助力服饰产业升级 广州/广东爆款裤料服务公司推荐 引言 随着快时尚产业迭代加速与消费需求个性化升级,服饰品牌对裤装面料的功能性、定制灵…

亲测好用9个AI论文平台,助你轻松搞定本科毕业论文!

亲测好用9个AI论文平台,助你轻松搞定本科毕业论文! AI 工具如何帮你轻松应对论文写作难题 对于很多本科生来说,写论文不仅是一项学术任务,更是一场心理和时间的双重挑战。从选题、查资料到撰写、修改,每一步都可能让人…

【图像融合】小波变换红外和可见光图像融合(含评价指标)【含GUI Matlab源码 14958期】

💥💥💥💥💥💥💥💥💞💞💞💞💞💞💞💞💞Matlab武动乾坤博客之家💞…

AI智慧餐食机物联网平台懒人专属寻投资人

AI智慧餐食机物联网平台懒人专属寻投资人智慧餐食机物联网平台的功能结构 该架构遵循分层设计原则,从设备端到用户端,层层递进,保证系统的解耦和可扩展性。 ​核心设计理念:​​ 平台化、模块化、微服务架构。所有…

【1 月小记】Part 3: 概率 DP - L

概率 DP 存档一些概率 / 期望 DP 的好题,我会持续更新 一、数学概念初步 概率的基本性质 互斥事件的性质 若 \(A\) 与 \(B\) 互为互斥事件,则 \[P(A\cup B)=P(A)+P(B) \]对立事件的性质 若 \(A\) 与 \(B\) 互为对立事…

Webpack 在异步请求 JS 文件时获取 JS Bundle 的机制

Webpack 在异步请求 JS 文件时获取 JS Bundle 的机制 Webpack 在处理代码分割(Code Splitting)后产生的异步 chunk(通常是 import() 动态导入)时,浏览器最终是怎么知道要去请求哪个 .js 文件,以及**请求回…

OLAP在大数据营销分析中的关键作用

OLAP在大数据营销分析中的关键作用:从原理到实战的深度解析 引言:当营销分析遇到“数据困境” 想象一个场景:某电商公司的营销总监正在筹备618大促。他想知道: 近30天来自抖音渠道、25-35岁女性、浏览过护肤品但未下单的用户有…

2026年口碑好的市政路灯,新农村路灯,锂电太阳能路灯厂家实力品牌推荐榜 - 品牌鉴赏师

引言在我国城市建设与发展的进程中,路灯作为必不可少的基础设施,其质量、性能与节能环保等特性愈发受到关注。国内相关行业协会为了引导市场健康发展、规范路灯企业的生产销售行为,依据一系列科学、严谨的测评方法,…

ArkTS问题:怎么提升代码的优先级呢?

ArkTS问题:怎么提升代码的优先级呢?如题,现在我这边有个问题。 代码片段: ... this.firstFunction(); this.secondFunction(); this.thirdFunction(); ... 现在,出现的情况就是,firstFunction()必须得执行完成,…