什么是SPI机制

news2024/12/27 13:08:12

什么是SPI机制


SPI机制是Java平台提供的一种强大的动态扩展机制,能够让程序在运行时灵活地加载和使用服务提供者的实现类。我们这里带大家简单的了解一下SPI机制是如何工作的

SPI(Service Provider Interface,服务提供者接口)机制是一种服务发现机制,它使得Java程序能够动态地查找、加载和使用服务的实现类。这种机制在Java应用中非常有用,尤其是在框架、库和插件开发中,可以提供很高的可扩展性和灵活性

SPI的核心思想是:面向接口编程面向实现动态加载。它允许开发者提供一组接口定义,服务提供者(服务实现类)可以通过实现这些接口并在运行时将它们加载到系统中。这样,不同的服务提供者(例如数据库驱动、XML解析器、日志系统等)可以以松耦合的方式与系统集成。

工作原理

上面说到SPI机制是一种服务发现机制,那么他是如何发现我们的服务呢?,他的工作原理主要有两点

  • 在ClassPath路径下的META-INF/services文件夹中,以接口的全限定名来命名文件名,对应的文件中应该写接口的实现
  • 使用ServiceLoader类动态加载实现类

假如此时我们定义了一个服务接口MyService

public interface MyService {
    void performAction();
}

我们又创建了他的两个实现类即服务提供者:MyServiceImplA和MyServiceImplB

public class MyServiceImplA implements MyService {
    @Override
    public void performAction() {
        System.out.println("Service Implementation A");
    }
}

public class MyServiceImplB implements MyService {
    @Override
    public void performAction() {
        System.out.println("Service Implementation B");
    }
}

然后我们在在项目的resources目录下创建META-INF/services/文件夹,并创建一个命名为接口全限定名的文件,例如这里com.example.MyService,文件内容为实现类的全限定名,每行一个:

com.example.MyServiceImplA
com.example.MyServiceImplB

这样SPI机制就可以找到我们的服务提供者即实现类,紧接着就可以使用ServiceLoader类动态加载实现类,ServiceLoader是Java提供的用于加载服务实现类的工具类。它负责从配置文件中读取实现类,并将它们实例化
我们可以通过以下方法拿到他的全部实现类:

ServiceLoader<MyService> serviceLoader = ServiceLoader.load(MyService.class);
for (MyService service : serviceLoader) {
    service.performAction();
}

这段代码会动态加载并实例化MyService接口的所有实现类,而这些实现类的信息需要在META-INF/services/目录下进行配置。也就是我们创建的com.example.MyService文件中的内容,加载里面所有列出的实现类(如ServiceImplA和ServiceImplB)它会通过反射机制实例化这些实现类,然后,for-each循环遍历所有加载的实现类,并调用它们的performAction()方法


此时你可能会想,SPI机制为什么要如此麻烦的拿到他的实现类再加载实例化,为什么不能直接在代码中new一个该接口的实现类并使用呢?

虽然通过new关键字直接实例化实现类的方式更简单,但它在以下几个方面存在不足:

  • 耦合度高:消费者代码与具体实现类强耦合,灵活性较差
  • 扩展性差:如果需要增加或更换实现类,需要修改代码
  • 无法动态发现:需要手动管理实现类,无法自动加载多种实现

而通过SPI机制,Java可以实现松耦合、可扩展性、动态加载和模块化。尤其在框架开发、插件系统、驱动管理(如JDBC)等场景中,SPI带来的好处远超直接new一个实现类的简单性。这也是为什么Java等大规模应用场景更倾向于使用SPI机制的原因


SPI机制应用

在JDBC中就是利用SPI机制来实现数据库驱动的加载,我们都知道JDBC为与数据库交互定义了一套标准接口,例如Connection、Statement、ResultSet等,这些接口是JDBC API的一部分
但是他是如何适配那么多种数据库呢,其实他并没有将这些接口实现,而是由数据库驱动程序实现,各个数据库供应商(如MySQL、Oracle等)会实现JDBC接口,并提供相应的驱动类。驱动类通常实现java.sql.Driver接口,这样就可以让我们使用JDBC技术去连接不同的数据库,我们只需要下载该数据库对应的驱动jar包,jar包种包含了该数据库对于JDBC各个接口的实现:

这里以mysql的驱动jar包为例:
将驱动jar包Add as Library后,可以看到他的文件目录,其中就有我们的META-INF/services,在下面我们可以看到有一个java.sql.Driver文件,这个文件的内容就是实现Driver接口的驱动类的全限定类名,打开我们发现对于MySQL驱动,文件内容是com.mysql.cj.jdbc.Driver,这就是实现Driver接口的实现类
在这里插入图片描述
在这里插入图片描述
当我们需要连接数据库时,通常使用DriverManager的getConnection方法获取连接。在JDBC的核心类DriverManager中,它通过ServiceLoader方法来获取并加载实现了java.sql.Driver接口的驱动类,并实例化这些驱动
在这里插入图片描述


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

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

相关文章

JavaScript while循环语句

While语句包括一个循环条件和一段代码块&#xff0c;只要条件为真&#xff0c;就不断循环执行代码块。 while(条件){语句;} var i0;while(i<100){console.log(i);i1;} 注意&#xff1a;所有的for循环都可以改写为while循环

Spring Boot 和 MyBatis-Plus凑一块儿了,这份教程你得看

一、引言 MyBatis-Plus 是 MyBatis 的增强版&#xff0c;提供了 CRUD 接口、分页插件、性能分析插件等特性&#xff0c;简化了开发过程。本文将详细介绍如何在 Spring Boot 项目中集成 MyBatis-Plus。 支持的数据看也越来越多&#xff0c;值得去搞一下&#xff0c;写了一个小例…

《PMI-PBA认证与商业分析实战精析》第5章 需求启发与分析

第5章 需求启发与分析 本章主要内容&#xff1a; 需求启发 需求分析 模型化与优化需求 记录、确认、核实和批准需求 本章涵盖的考试重点&#xff1a; 需求启发的四项活动 需求启发的八项技术 启发提问的四种类型问题 启发原型的类型 访谈的四种分类 观察技术的四种类…

华三资源

华三华三官方网站华三公司官网新华三 - 融绘数字未来&#xff0c;共享美好生活华三华三文档中心华三文档资源文档中心-新华三集团-H3C华三华三 ICT百科华三 ICT知识百科H3C ICT知识百科-新华三集团-H3C华三华三文档高级查找高级文档搜索新华三 - 融绘数字未来&#xff0c;共享美…

已解决:Could not find artifact xxx

已解决&#xff1a;Could not find artifact xxx 文章目录 写在前面问题描述报错原因分析 解决思路解决办法1. 检查依赖声明的正确性2. 检查远程仓库配置3. 检查网络连接4. 清理本地缓存并强制更新5. 手动上传依赖到私有仓库6. 检查本地仓库是否已被损坏 总结 写在前面 在使用…

V2V迁移:vsphere至openstack

预检查 检测待迁移实例是否已安装并配置virtio相关的块设备驱动、网卡驱动&#xff0c;linux包括kernel、initramfs&#xff0c;windows包括磁盘控制器、网卡。 Linux 系统检查 Virtio 驱动 Windows 系统检查 Virtio 驱动 环境 1、下载安装ovftool 2、安装qemu-kvm&#x…

数据结构-二叉树介绍及其在Java中遍历算法实现

一、二叉树介绍 1、二叉树(Binary tree)的定义 二叉树(binary tree)是树形结构的一个重要类型,是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右…

Angular基础学习(入门 --> 入坑)

目录 一、Angular 环境搭建 二、创建Angular新项目 三、数据绑定 四、ngFor循环、ngIf、ngSwitch、[ngClass]、[ngStyle]、管道、事件、双向数据绑定--MVVM 五、DOM 操作 &#xff08;ViewChild&#xff09; 六、组件通讯 七、生命周期 八、Rxjs 异步数据流 九、Http …

SuperMap iClient for MapLibreGL 根据SQL条件过滤显示动态图层

查阅发现iClient 有子图层控制类 LayerStatus 可实现&#xff1a;子图层显示参数类。此类存储了各个子图层的名称、是否可见的状态、SQL 过滤条件等参数。 API详情&#xff1a;http://support.supermap.com.cn:8090/iserver/iClient/forJavaScript/docs/maplibregl/LayerStatus…

java_整型

1.整数类型 2.整型细节 Java各整数类型有固定的范围和字段长度&#xff0c;不受具体OS【操作系统】的影响&#xff0c;以保证Java程序的可移植性 Java的整型常量&#xff08;具体值&#xff09;默认为int型&#xff0c;声明long型常量后需加"l"或"L" pu…

计算机网络:计算机网络体系结构 —— OSI 模型 与 TCP/IP 模型

文章目录 计算机网络体系结构OSI 参考模型TCP/IP 参考模型分层的必要性物理层的主要问题数据链路层的主要问题网络层的主要问题运输层的主要问题应用层的主要问题 分层思想的处理方法发送请求路由器转发接受请求发送响应接收响应 计算机网络体系结构 计算机网络体系结构是指将…

一文说完c++全部基础知识,IO流(二)

一、IO流 流、一连串连续不断的数据集合。 看下图&#xff0c;继承关系 using namespace 流类的构造函数 eg:ifstream::ifstream (const char* szFileName, int mode ios::in, int); #include <iostream> #include <fstream> using namespace std; int main()…

堆排序算法详解:原理与Python实现

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

注册安全分析报告:科研诚信查询平台无验证方式导致安全隐患

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

《MoCo:Momentum Contrast for Unsupervised Visual Representation Learning》中文校对版

系列文章目录 文章目录 系列文章目录摘要1.简介2.相关工作3.方法3.1.作为字典查找的对比学习2、3、 五、1、2、3、 六、1、2、3、 七、1、2、3、 八、1、2、3、 摘要 我们提出了用于无监督视觉表示学习的动量对比&#xff08;MoCo&#xff09;。从对比学习[29]作为字典查找的角…

死锁的成因与解决方案

目录 死锁的概念与成因 栗子 死锁的情况 哲学家问题 如何避免死锁 必要条件 死锁的解决方案 总结 死锁的概念与成因 多个线程同时被阻塞,他们中的其中一个或者全部都在等待某个资源的释放,导致线程无限期被阻塞,程序无法停止 栗子 我和美女a出去吃饺子,吃饺子要醋和酱油…

【EXCEL数据处理】000011 案列 EXCEL带有三角形图标的单元格转换,和文本日期格式转换。

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】000011 案列 EXCEL带有三角形图标的单元格转换。使用…

Pikachu-csrf-CSRF(get)

登陆&#xff0c;修改个人信息&#xff1b;发现这是个get请求 把请求连接复制出来 ​http://192.168.3.224:8082/vul/csrf/csrfget/csrf_get_edit.php?sex1&phonenum1&add2&email3&submitsubmit就是 get请求的csrf 攻击payload

阿里云域名解析和备案

文章目录 1、域名解析2、新手引导3、ICP备案 1、域名解析 2、新手引导 3、ICP备案

重放Net-NTLM HASH 实验

先记录relay2SMB的&#xff0c;relay2LDAP的会补上来。 后面的一些利用EXCHANGE服务器的writedacl权限来relay2EWS DCSync的等我安了EXCHANGE再说吧2333。。 1. relay2SMB 0x01 smbrelayx.py 监听Net-NTLM&#xff0c;然后中继到win2008的SMB服务&#xff0c;执行whoami命…