java的SPI机制

article/2025/6/10 15:34:49

SPI(Service Provider Interface)是java提供的一种服务发现机制。允许你定义一个接口或抽象类,然后由第三方实现这个接口,并在运行时动态加载这些实现类

核心思想是:面向接口编程,解耦接口与实现

核心组件

接口/抽象类、实现类、配置文件、ServiceLoader(JDK提供的工具类)

//1.定义接口或抽象类
public interface Animal {void speak();
}
//2.编写多个实现类
public class Cat implements Animal {public void speak() {System.out.println("Meow");}
}public class Dog implements Animal {public void speak() {System.out.println("Woof");}
}
//3.创建配置文件,在 resources/META-INF/services/ 目录下创建一个文件:com.example.Animal
com.example.Cat
com.example.Dog
//4.使用ServiceLoader加载实现类
ServiceLoader<Animal> serviceLoader = ServiceLoader.load(Animal.class);for (Animal animal : serviceLoader) {animal.speak();
}
等价于:
Iterator<Animal> iterator = serviceLoader.iterator();
while (iterator.hasNext()) {Animal animal = iterator.next();animal.speak();
}//输出:
Meow
Woof

工作原理:

实际上就是ServiceLoader.load这一步

首先先理解一下ServiceLoader这个类,这个类实现了Iterable接口

作用是根据接口或抽象类,在运行时动态加载所有实现了该接口的类

《可以看作是一个插件发现器,能自动扫描项目中的jar包,找到符合某个接口的所有实现类,并创建他们的实例》

流程:

读取配置文件中的内容,获取实现类的类名

使用类加载器去加载类

调用无参构造函数去实例化对象(懒加载+无参构造函数)

返回serviceLoader(虽然不是一个iterator,但是可以被增强for循环遍历)

至于这些所有的实现类的实例,会放入serviceloader的一个缓存池中,而且是懒加载的,第一次用到时才加载

应用场景:

优缺点:

优点:

        接口和实现分离

        新增实现无需修改代码

        支持热插拔,插件化系统

        标准化配置:统一都使用配置文件META-INF/services配置

缺点:

        一次性加载所有的实现类

        只能按照配置文件中的顺序加载

        不支持IOC容器继承

        加载失败不会抛出异常,静默跳过

SPI与springIOC对比:

SPI的使用场景是标准化接口、插件化系统,但是对实例实际上只有创建,没有管理的能力(生命周期、依赖注入等),而且不支持条件加载

springIOC对实例对象有很强的管理以及支持一些自定义的配置,功能非常灵活强大

所以在实际应用中,例如在springboot中对数据库驱动的加载的时候,实际上是底层原理是SPI,将SPI创建出来的数据库驱动实例通过@bean注解返回给IOC容器实现了灵活化管理和应用

SPI和API的区别:

(图来自javaguide)

API是面向“使用者”的,调用方直接使用来实现功能

SPI是面向“实现者”的

我觉得主要意思就是,API我在为了实现这个功能调用这个接口的时候,具体的方法是已经写好的,我直接用就好了,但是SPI是我用这个接口的时候,这个接口只是提供了一种通用的方法,但是具体怎么实现是可以自定义的(不知道是不是这样)

ai一句话总结为:API 是“我调用你”,SPI 是“你实现我”

SPI是一种扩展机制,API是一种调用机制


http://www.hkcw.cn/article/OrurVeEecl.shtml

相关文章

SpringCloud 分布式锁Redisson锁的重入性 高并发 获取锁

介绍 Redisson 的锁支持 可重入性&#xff0c;这意味着同一个线程在获取锁后&#xff0c;如果再次尝试获取该锁&#xff0c;它可以成功地获得锁&#xff0c;而不会被阻塞。 每次一个线程成功获取锁后&#xff0c;它的持有次数会增加。当线程再次获取该锁时&#xff0c;Rediss…

PyTorch--池化层(4)

池化层&#xff08;Pooling Layer&#xff09; 用于降低特征图的空间维度&#xff0c;减少计算量和参数数量&#xff0c;同时保留最重要的特征信息。 池化作用&#xff1a;比如1080p视频——720p 池化层的步长默认是卷积核的大小 ceil 允许有出界部分&#xff1b;floor 不允许…

【自动思考记忆系统】demo (Java版)

背景&#xff1a;看了《人工智能》中的一段文章&#xff0c;于是有了想法。想从另一种观点&#xff08;⭕️&#xff09;出发&#xff0c;尝试编码&#xff0c;告别传统程序员一段代码解决一个问题的方式。下图是文章原文和我的思考涂鸦✍️&#xff0c;于是想写一个自动思考记…

小白的进阶之路系列之十二----人工智能从初步到精通pytorch综合运用的讲解第五部分

在本笔记本中,我们将针对Fashion-MNIST数据集训练LeNet-5的变体。Fashion-MNIST是一组描绘各种服装的图像瓦片,有十个类别标签表明所描绘的服装类型。 # PyTorch model and training necessities import torch import torch.nn as nn import torch.nn.functional as F impor…

pytorch3d+pytorch1.10+MinkowskiEngine安装

1、配置pytorch1.10cuda11.0 pip install torch1.10.1cu111 torchvision0.11.2cu111 torchaudio0.10.1 -f https://download.pytorch.org/whl/cu111/torch_stable.html 2、配置 MinkowskiEngine库 不按下面步骤&#xff0c;出现错误 1、下载MinkowskiEngine0.5.4到本地 2、查看…

ORACLE 缺失 OracleDBConsoleorcl服务导致https://xxx:port/em 不能访问

这个原因是&#xff0c;操作过一下 ORCL的服务配置变更导致的。 再PATH中添加个环境变量&#xff0c;路径如下 管理员权限运行cmd 等待创建完成 大概3分钟 查看服务 点击第一个访问&#xff0c;下图登录后的截图

分布式流处理与消息传递——向量时钟 (Vector Clocks) 算法详解

Java 实现向量时钟 (Vector Clocks) 算法详解 一、向量时钟核心原理 #mermaid-svg-JcZ1GT0r1ZNSy6W7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JcZ1GT0r1ZNSy6W7 .error-icon{fill:#552222;}#mermaid-svg-JcZ…

深入浅出:Oracle 数据库 SQL 执行计划查看详解(1)——基础概念与查看方式

背景 在当今的软件开发领域&#xff0c;尽管主流开发模式往往倾向于采用单表模式&#xff0c;力图尽可能地减少表之间的连接操作&#xff0c;以期达到提高数据处理效率、简化应用逻辑等目的。然而&#xff0c;对于那些已经上线运行多年的运维老系统而言&#xff0c;它们内部往…

多模态大语言模型arxiv论文略读(104)

Talk Less, Interact Better: Evaluating In-context Conversational Adaptation in Multimodal LLMs ➡️ 论文标题&#xff1a;Talk Less, Interact Better: Evaluating In-context Conversational Adaptation in Multimodal LLMs ➡️ 论文作者&#xff1a;Yilun Hua, Yoav…

【Oracle】游标

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 游标基础概述1.1 游标的概念与作用1.2 游标的生命周期1.3 游标的分类 2. 显式游标2.1 显式游标的基本语法2.1.1 声明游标2.1.2 带参数的游标 2.2 游标的基本操作2.2.1 完整的游标操作示例 2.3 游标属性2.3.1…

Ethernet/IP转DeviceNet网关:驱动大型矿山自动化升级的核心纽带

在大型矿山自动化系统中&#xff0c;如何高效整合新老设备、打通数据孤岛、实现统一控制&#xff0c;是提升效率与安全的关键挑战。JH-EIP-DVN疆鸿智能EtherNet/IP转DeviceNet网关&#xff0c;正是解决这一难题的核心桥梁&#xff0c;为矿山各环节注入强劲连接力&#xff1a; …

Nginx + Tomcat 负载均衡、动静分离群集

一、 nginx 简介 Nginx 是一款轻量级的高性能 Web 服务器、反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;在 BSD-like 协议下发行。其特点是占有内存少&#xff0c;并发能力强&#xff0c;在同类型的网页服务器中表现优异&#xff0c;常用…

5.Nginx+Tomcat负载均衡群集

Tomcat服务器应用场景&#xff1a;tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP程序的首选。一般来说&#xff0c;Tomcat虽然和Apache或…

【算法设计与分析】实验——汽车加油问题, 删数问题(算法实现:代码,测试用例,结果分析,算法思路分析,总结)

说明&#xff1a;博主是大学生&#xff0c;有一门课是算法设计与分析&#xff0c;这是博主记录课程实验报告的内容&#xff0c;题目是老师给的&#xff0c;其他内容和代码均为原创&#xff0c;可以参考学习&#xff0c;转载和搬运需评论吱声并注明出处哦。 4-1算法实现题 汽车…

网络爬虫 - App爬虫及代理的使用(十一)

App爬虫及代理的使用 一、App抓包1. App爬虫原理2. reqable的安装与配置1. reqable安装教程2. reqable的配置3. 模拟器的安装与配置1. 夜神模拟器的安装2. 夜神模拟器的配置4. 内联调试及注意事项1. 软件启动顺序2. 开启抓包功能3. reqable面板功能4. 夜神模拟器设置项5. 注意事…

SQLite详细解读

一、SQLite 是什么&#xff1f; SQLite 是一个嵌入式关系型数据库管理系统&#xff08;RDBMS&#xff09;。它不是像 MySQL 或 PostgreSQL 那样的客户端-服务器数据库引擎&#xff0c;而是一个自包含的、无服务器的、零配置的、事务性的 SQL 数据库引擎。 核心特点 嵌入式/库…

线程池详细解析(三)

本章我们来讲一讲线程池的最后一个方法shutdown&#xff0c;这个方法的主要作用就是将线程池进行关闭 shutdown&#xff1a; public void shutdown() {ReentrantLock var1 this.mainLock;var1.lock();try {this.checkShutdownAccess();this.advanceRunState(0);this.interrup…

口碑对比:杭州白塔岭画室和燕壹画室哪个好?

从口碑方面来看&#xff0c;杭州燕壹画室和白塔岭画室各有特点&#xff0c;以下是具体分析&#xff1a; 燕壹画室 教学成果突出&#xff1a; 其前身燕壹设计工作室在2019 - 2023年专注美院校考设计&#xff0c;有一定的教学积淀&#xff0c;2023年转型后第一年攻联考就斩获浙…

车载雷达:超声波雷达、毫米波雷达、激光雷达相关技术场景介绍和技术比较

随着技术发展,如今的汽车智能化程度越来越高,配备的传感器也越来越多,特别是与辅助驾驶相关的汽车雷达,它们如同汽车的 “眼睛”,帮助车辆感知周围环境。为了适配不同的使用场景和功能需求,汽车雷达也分为很多类型,并且各具特点。 一、技术特点 一)超声波雷达 超声波…

Spring AI Advisor机制

Spring AI Advisors 是 Spring AI 框架中用于拦截和增强 AI 交互的核心组件&#xff0c;其设计灵感类似于 WebFilter&#xff0c;通过链式调用实现对请求和响应的处理5。以下是关键特性与实现细节&#xff1a; 核心功能 ‌1. 请求/响应拦截‌ 通过 AroundAdvisor 接口动态修…