SPI机制是什么?

2023-11-17

一、SPI机制是什么?

        spi全称为 (Service Provider Interface),是JDK内置的一种服务提供发现机制。SPI是一种动态替换发现的机制,一种解耦非常优秀的思想。

        spi的工作原理: 就是ClassPath路径下的META-INF/services文件夹中, 以接口的全限定名来命名文件名,文件里面写该接口的实现。然后再资源加载的方式,读取文件的内容(接口实现的全限定名), 然后再去加载类。

spi可以很灵活的让接口和实现分离, 让api提供者只提供接口, 第三方来实现。

 优点:

  • 使用Java SPI机制的优势是实现解耦,使得第三方服务模块的装配控制的逻辑与调用者的业务代码分离,而不是耦合在一起。应用程序可以根据实际业务情况启用框架扩展或替换框架组件。

缺点:

  • 虽然ServiceLoader也算是使用的延迟加载,但是基本只能通过遍历全部获取,也就是接口的实现类全部加载并实例化一遍。如果你并不想用某些实现类,它也被加载并实例化了,这就造成了浪费。获取某个实现类的方式不够灵活,只能通过Iterator形式获取,不能根据某个参数来获取对应的实现类。
  • 多个并发多线程使用ServiceLoader类的实例是不安全的。

二、SPI如何使用

        那么现在有这样的场景:当我的项目里面有什么支付模块我就使用什么样的支付模块,比如说有支付宝支付模块就选择支付宝、有微信支付模块我就选择微信支付、同时有多个的时候,我默认选择第一个,此时我们就可以使用SPI,先看下如何使用。

1、创建META-INF/services文件夹,然后创建一个以Pay接口全限定名为名字的文件

2、在文件中编写想要实现哪个Pay的实现类(AliPay,WechatPay,BankCardPay),注意也要是全限定名。假如是是支付宝支付的模块,上面文件的内容:com.taolong.dubbo.spi.strategy.AliPay

 3、获取Pay并调用

获取并调用的逻辑,我就修改下上面的策略模式中的Context的invokerStrategy方法,这里假设默认使用第一个

public void invokeStrategy(){
    ServiceLoader<Pay> payServiceLoader = ServiceLoader.load(Pay.class);
    Iterator<Pay> iterator = payServiceLoader.iterator();
    if (iterator.hasNext()){
        iterator.next().pay();
    }
}

三、SPI的优秀实现案例

        我们来看一个真实的使用上述SPI的例子—数据库驱动(Driver)。

        我们知道,当我们的项目里面使用引用了mysql的驱动pom依赖时,我们的项目里面会自动选择使用mysql的驱动,我们甚至不需要手动去加载。我们来看看它的具体实现。

1、首先看一下java.sql.Driver的类,这里面也是相当于定义了一个规范

2、其次看mysql驱动包的META-INF/services文件夹下面有没有指定的文件

很熟悉,命名就是java.sql.Driver

3、打开文件查看一下文件内容

 

        这里面就能看到我们的mysql的驱动了,到这里基本上就确认这也是使用SPI实现的,顺便说一下,现在为什么我们不需要使用Class.forName()去加载驱动了,这是因为DriverManager使用SPI的机制已经帮我们加载好了,我们来看看DriverManager的类

 不管是文件名还是文件内容都是全限定名,所以通过反射很容易创建相应的类

在现有框架中的使用

        其实了解SPI机制是因为最近看SpringBoot代码的时候发现的,我们知道在SprngBoot中好多的配置和实现都有默认的实现,我们只需要修改部分配置,比如数据库配置,我们只要在配置文件中写上对应的url,username,password就可以使用了。其实他这边用的就是SPI的方式实现的

不过Spring使用的只是和JDK中的原理相同而已。

JDK使用的工具类是ServiceLoader

Spring中使用的类是SpringFactoriesLoader,在 org.springframework.core.io.support包中

区别:

文件路径不同 spring配置放在 META-INF/spring.factories中

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SPI机制是什么? 的相关文章

随机推荐

  • Lumen 5.2 中配置邮件

    本文转自 https laravel china org topics 1974 Lumen中的邮件配置好了之后还是很简单的 但是配置过程官方文档省略了太多 先来扒一扒遇到的坑 Class mailer does not exist 这个是
  • Mysql内置函数全解析——Mysql初级(三)

    一 前言 在关系型数据库使用的过程中 我们总会对DB里面的数据做各种不同形式的转换 字符串处理等基本操作 本文将会比较系统的学习总结Mysql中的各种内置函数 这是一个系列的文章 感兴趣的小伙伴可以关注一下哦 本文的行文思路是这样的 因为M
  • 微信小程序——获取绑定事件元素的ID

    小程序list数据带值跳转 一般直接通过设置item的id来标识或者通过设置键值data xxxx的方式标识 如下图所示 解析出来的结果如下图 我们看到它在元素上绑定了一个checkSchoolLogin事件 触发这个事件时需要获取该元素的
  • 关于单链表结构体定义结点时 LNode *LinkList的理解

    typedef struct LNode ElemType data 数据域 struct LNode next 指针域 LNode LinkList 先说结论 这个就可以直接理解为 第一个是便于定义变量的类型为LNode 如果没有使用ty
  • springboot配置来连接多个mysql数据库

    1 在yml里配置多数据库 spring datasource app1 jdbc url jdbc mysql localhost 3306 data1 useUnicode true characterEncoding UTF 8 se
  • leetcode-143-重排链表

    题意描述 给定一个单链表 L 的头节点 head 单链表 L 表示为 L0 L1 Ln 1 Ln 请将其重新排列后变为 L0 Ln L1 Ln 1 L2 Ln 2 不能只是单纯的改变节点内部的值 而是需要实际的进行节点交换 解题思路 Ali
  • 【机器学习】为什么需要对数值型的特征做归一化(Normalization)?

    目录 为什么需要对数值型的特征做归一化 一 概念定义 二 标准化 归一化的原因 用途 2 1 原因 三 数据归一化的影响 四 常用的3种归一化方法 4 1 归一化公式 4 1 1 线性归一化 Min Max Scaling 即我们一般指的归
  • SpringBoot 整合Activiti(二)——流程审批完整示例

    前两天做了一个SpringBoot整合Activiti的完整示例 功能包括 退回 通过 节点条件 指定办理人 生成流程图 高亮显示已办节点 查询任务列表 办理人 等 下面先简单记录 含完整代码 十六上班后再详细补充 1 画流程图 高亮生成的
  • 《视觉slam十四讲》之第7讲-特征提取与匹配

    特征 特征为图像中具有代表性的区域 可以为角点 边缘和区块等 特征是图像信息的另一种数字表达形式 特征具有以下性质 可重复性 Repeatability 相同的 区域 可以在不同的图像中被找到 可区别性 Distinctiveness 不同
  • Linux运行shell脚本时报错"syntax error near unexpected token `$'\r''

    Linux运行shell脚本时 常常会发生syntax error near unexpected token r 或者syntax error unexpected end of file等 诸如此类的报错信息出现的原因是因为在编写脚本内
  • Shell编程中脱字符(^)的用法

    cat configs signatures tmp 将configs signatures tmp文件内容作为grep命令的输入 grep v v是grep排除的参数 将configs signatures tmp除去空行的内容作为sor
  • 蓝桥杯在哪下载准考证

    点击自己的头像 gt 我的大赛 gt 会出现如下 gt 点击Java软件开发 根据自己报的方向 gt 可以看到考试信息 gt 下载准考证即可 转载于 https blog 51cto com 13534640 2090954
  • Kafka消息阻塞

    转自 http jis117 iteye com blog 2279519 hi all 大家都很关心kafka消息阻塞的情况 感谢RoctetMQ给我们的教训 Kafka上线也有一段时间了 确实有出现过消息阻塞的情况 虽然不影响业务而且用
  • 判断逻辑关系的运算符 && 与,

    package com test basic chapter2 功能 判断逻辑关系的运算符 与 或 非 与 同为真即真 或 有真即真 非 public class LogicalOperators public static void ma
  • Java中map集合,你真的了解吗?

    在Java编程中 map集合是一个非常重要的数据结构 它可以存储键值对 并且可以根据键快速查找对应的值 今天 我们就来详细介绍一下Java中的map集合 首先 让我们来了解一下map集合的基本概念 在Java中 map集合是一个接口 它有多
  • padding的四个参数_Google Flutter 布局(二)-Padding、Align、Center详解

    1 1 简介 Padding在Flutter中用的也挺多的 作为一个基础的控件 功能非常单一 给子节点设置padding属性 写过其他端的都了解这个属性 就是设置内边距属性 内边距的空白区域 也是widget的一部分 Flutter中并没有
  • 深入理解Java——从入门到精通

    标题 深入理解Java 从入门到精通 Java是一门广泛应用于软件开发领域的高级编程语言 它的特点包括强大的跨平台性 面向对象的编程范式 丰富的类库以及良好的安全性 无论是在企业级应用开发 移动应用开发还是嵌入式系统开发中 Java都扮演着
  • [分享]如何使用Angular中的自定义校验器

    在Angular的开发中表单是必不可少的 由此引出的表单校验也是万万不可缺少的 解决方法一 全部使用ngModel 双向绑定数据 在最后的submit点击时进行所有表单的校验 这样做固然没有什么问题 而且代码写的也和我们之前使用jQuery
  • 单元格法近似求解多边形最大内接矩形问题【思路讲解+java实现】

    文章目录 问题描述 问题解决方案 多边形网格化 区分每个单元格是在多边形内部还是外部 根据已标记单元格寻找最大内接矩形 剪枝优化 多角度旋转 案例测试 代码实现 说明 问题描述 给定一个多边形的点集 希望找出多边形内部面积最大的矩形 该问题
  • SPI机制是什么?

    一 SPI机制是什么 spi全称为 Service Provider Interface 是JDK内置的一种服务提供发现机制 SPI是一种动态替换发现的机制 一种解耦非常优秀的思想 spi的工作原理 就是ClassPath路径下的META