SPI 与 API 的区别详解

在 Java 以及各种框架开发中,我们经常会听到 APISPI 这两个概念。它们看起来都和"接口"有关,但实际使用场景和设计思想却完全不同。本文将从定义、原理、使用方式和实际案例多个角度介绍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 主要依赖以下机制:

  1. 定义接口
  2. META-INF/services 目录下配置实现类
  3. 通过 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

参考

SPI 和 API 有什么区别?--JavaGuide

【Java面试训练营-API和SPI的区别】

相关推荐
专注VB编程开发20年2 小时前
PLC协议:Modbus.Device(NModbus4)和手动 Socket.BeginConnect (APM异步编程模型)对比
网络·网络协议·tcp/ip·plc
济6172 小时前
I.MX6U 开发板网络环境搭建---- TFTP 环境搭建-- Ubuntu20.04
linux·网络·驱动开发
阿钱真强道2 小时前
14 ThingsBoard实战:从零搭建设备配置+设备,完成MQTT温湿度上行/目标温度下行测试(对比JetLinks)
java·网络·python·网络协议
dashizhi20152 小时前
如何禁止外部电脑接入内网、防止外来设备连接内部wifi?
网络·智能路由器
!沧海@一粟!2 小时前
Linux-配置虚拟IP实例
linux·网络
凉、介2 小时前
关于家用路由器的一些知识
网络·笔记·学习·智能路由器
济6172 小时前
I.MX6U 开发板网络环境搭建----(电脑 WiFi 上网,开发板和电脑直连)--虚拟机双网口实现-- Ubuntu20.04
linux·网络·电脑
执笔论英雄2 小时前
【大模型推理】 通过TokenWeave 学习chunked prefill 的缺点。
服务器·网络·学习
匀泪3 小时前
云原生(Keepalived概述)
网络