在 Java 以及各种框架开发中,我们经常会听到 API 和 SPI 这两个概念。它们看起来都和"接口"有关,但实际使用场景和设计思想却完全不同。本文将从定义、原理、使用方式和实际案例多个角度介绍SPI 与 API 的区别。
文章目录
-
- [一、什么是 API?](#一、什么是 API?)
-
- [1. API 的定义](#1. API 的定义)
- [2. API 的特点](#2. API 的特点)
- [3. API 的使用示例](#3. API 的使用示例)
- [二、什么是 SPI?](#二、什么是 SPI?)
-
- [1. SPI 的定义](#1. SPI 的定义)
- [2. SPI 的核心思想](#2. SPI 的核心思想)
- [3. SPI 的工作机制(以 Java 为例)](#3. SPI 的工作机制(以 Java 为例))
- [三、SPI 与 API 的核心区别](#三、SPI 与 API 的核心区别)
- 四、从控制权角度理解区别
- 五、经典应用场景对比
-
- [1. API 的典型应用](#1. API 的典型应用)
- [2. SPI 的典型应用](#2. SPI 的典型应用)
- [六、为什么需要 SPI?](#六、为什么需要 SPI?)
- [七、SPI 与 API 的组合使用](#七、SPI 与 API 的组合使用)
- 八、面试常见问题总结
-
- [1. SPI 和 API 最大区别是什么?](#1. SPI 和 API 最大区别是什么?)
- [2. SPI 的本质思想是什么?](#2. SPI 的本质思想是什么?)
- [3. SPI 一定比 API 好吗?](#3. SPI 一定比 API 好吗?)
- 参考

一、什么是 API?
1. API 的定义
API(Application Programming Interface,应用程序编程接口),是程序对外提供的一组标准调用方式。
简单来说:
API 是"我提供功能,你来调用"。
开发者通过 API,可以直接使用别人已经封装好的能力,而无需关心内部实现。
2. API 的特点
API 通常具有以下特征:
- 由服务提供方设计
- 面向使用者
- 功能固定
- 调用方式明确
- 使用者不能随意修改实现
3. API 的使用示例
以 Java 集合框架为例:
java
List<String> list = new ArrayList<>();
list.add("Hello");
这里:
List是接口add()是 API- 我们是调用方
开发者只需要使用 API,而不关心底层如何实现。
二、什么是 SPI?
1. SPI 的定义
SPI(Service Provider Interface,服务提供者接口),是一种"面向扩展"的接口机制。
简单理解:
SPI 是"我定义规范,你来实现"。
框架定义接口,第三方提供实现,运行时动态加载。
2. SPI 的核心思想
SPI 的本质思想是:
- 解耦框架与实现
- 支持插件化
- 支持动态扩展
框架本身不关心具体实现是谁,只负责加载和调用。
3. SPI 的工作机制(以 Java 为例)
Java SPI 主要依赖以下机制:
- 定义接口
- 在
META-INF/services目录下配置实现类 - 通过
ServiceLoader加载
示例结构:
plain
META-INF/services/
com.example.MyService
文件内容:
plain
com.example.impl.MyServiceImpl
加载方式:
java
ServiceLoader<MyService> loader = ServiceLoader.load(MyService.class);
for (MyService service : loader) {
service.execute();
}
三、SPI 与 API 的核心区别
| 对比维度 | API | SPI |
|---|---|---|
| 设计方向 | 面向调用者 | 面向扩展者 |
| 主导方 | 服务提供方 | 框架制定方 |
| 使用者角色 | 使用接口 | 实现接口 |
| 扩展能力 | 弱 | 强 |
| 动态加载 | 一般不支持 | 支持 |
| 典型场景 | 工具库、SDK | 插件体系、框架扩展 |
一句话总结:
API 面向"用",SPI 面向"扩"。
四、从控制权角度理解区别
理解 SPI 与 API,关键在于"控制权"问题。
API:控制权在框架
- 框架定义功能
- 用户调用功能
- 用户被动使用
示意:

SPI:控制权在用户
- 框架定义接口
- 用户实现接口
- 框架回调用户代码
示意:

这其实就是著名的:
控制反转(IOC / Inversion of Control)思想。
五、经典应用场景对比
1. API 的典型应用
常见 API 场景:
- JDK 工具类
- 第三方 SDK
- HTTP 接口
- 数据库驱动调用
示例:
java
HttpClient.send(request);
2. SPI 的典型应用
常见 SPI 场景:
- JDBC 驱动加载
- 日志框架扩展
- Spring 扩展点
- Dubbo 扩展机制
示例:
java
DriverManager.getConnection(url);
底层通过 SPI 自动加载驱动。
六、为什么需要 SPI?
如果只有 API,会有什么问题?
- 框架扩展性差
- 强依赖实现
- 难以插件化
SPI 的出现解决了这些问题:
- 支持多实现
- 解耦核心逻辑
- 支持第三方扩展
- 方便升级维护
七、SPI 与 API 的组合使用
在实际项目中,SPI 和 API 往往是配合使用的。
典型模式:
- API:提供基础能力
- SPI:提供扩展能力
示意:
plain
框架 = API + SPI
例如:
- Spring
- Dubbo
- MyBatis
都同时使用了 API 和 SPI。
API 是"我写好功能给你用",SPI 是"我定好规范让你扩展"。
八、面试常见问题总结
1. SPI 和 API 最大区别是什么?
答:
- API:调用方使用
- SPI:调用方实现
2. SPI 的本质思想是什么?
答:
- 控制反转
- 面向扩展
- 插件化
3. SPI 一定比 API 好吗?
答:不是。
- 简单系统用 API 即可
- 可扩展系统才需要 SPI