Java-SPI应用场景以及原理

一、前言(介绍)

Java SPI(Service Provider Interface)是 Java 官方提供的一种服务发现机制 ,它允许在运行时动态的加载实现特定接口的类

通过定义接口,实现类去具体实现,然后使用方根据自己项目扫描出来的实现类来调用(依赖 jar),实现可插拔式的开发。

二、基础 Demo

1、定义 Service spi

csharp 复制代码
public interface CarApi {
    String builderCar();
}

2、实现 Service Provider

typescript 复制代码
public class MiCarServiceImpl implements CarApi {
    @Override
    public String builderCar() {
        return "小米电车su7.。。。。。。。。。。。。。。。。。";
    }
}

3、在 Serivice Provider 的 resources目录下,创建META-INF/services目录

4、服务发现

vbnet 复制代码
1、注入依赖(Service Provider 的jar包)
2、调用服务
public void testCar(){
        ServiceLoader<CarApi> carApis = ServiceLoader.load(CarApi.class);
        Iterator<CarApi> iterator = carApis.iterator();
        while (iterator.hasNext()){
            CarApi next = iterator.next();
            System.out.println(next.builderCar());
        }
}

代码地址:gitee.com/boge1022/ja...

三、实现原理

工作流程:

角色分类:

  • Service Api :是一个公开的接口或者抽象类,定义了一个抽象的功能模块
  • Serivice Provider:是 Service api 接口的一个实现类
  • ServiceLoader:是 SPI 机制中核心组件,负责在运行时发现并加载 Service Provider

Service Provider 规范要素:

文件路径:必须在 jar 包中的 META-INF/services 目录下

文件名称:Service Api 接口全限类名

文件内容:Service Provider 实现类全限类名,如果有多个实现类,那么每一个实现类单独占用一行

注意:Service Provider 实现类必须具备无参的构造方法。因为后面是通过反射技术创建对象

原理:

SPI 加载器:使用线程上下文加载器,默认是 ApplicationClassloader 加载器。

通过固定格式 META-INF/service+Service Api 接口全限类名 来使用 inputStream 流读取文件信息,拿到实现类的全限类名,最后通过反射的方式实例化对象,放入缓存中

四、应用场景(待补充)

通常用于一个方法多个实现,但具体实现内容选取取决于依赖的服务提供者。

1、日志框架slf4j

2、DriverManager 驱动选取策略

3、sharding-jdbc 主键生成策略

五、总结

Java 中的 SPI 提供一种特殊的服务发现机制,通过接口将服务调用和服务提供分隔开,将接口提供给第三方实现扩展,体现了依赖倒置的设计思想,代码解藕。

个人总结:Java 中的 SPI 的理解

1、从思想层面来理解:SPI 提供了一种特殊的服务发现机制,类似于策略模式的思想,通过依赖的提供者来调用具体的实现类

2、从技术层面来说:主要是将服务调用者和服务提供者分隔开,通过服务发现来获取具体的提供者实现(jar 包**)**

相关推荐
马良神笔1 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD1 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端
高频因子挖掘机2 小时前
A股量化从日线升级到5分钟线:数据量增加后最先暴露哪些工程问题?
后端·github·api
高频因子挖掘机2 小时前
历史行情返回顺序变了,为什么按行号计算指标很危险?
后端·github·api
团子哒哒4 小时前
数组、切片和Map
后端
专注仿真4 小时前
ThinkPHP6 API接口开发实例:从零搭建RESTful风格接口
后端·php·restful
开心猴爷4 小时前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
1m555555554 小时前
RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?
后端·面试
易小尊4 小时前
我的模型在 65% 以上时准得可怕,在 50% 时像在掷硬币
后端
用户2788607285674 小时前
fallback 会盖掉平台提示词:system、空数组和 systemAppend 的差别
前端·后端