Java SPI机制

2023-11-10

一、SPI机制简介

SPI的全名为Service Provider Interface.java spi机制的思想: 系统里抽象的各个模块,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是解耦

网上找了一个认为比较容易理解的例子:JDK中有支持音乐播放,假设只支持mp3的播放,有些厂商想在这个基础之上支持mp4播放,有的想支持mp5播放,而这些厂商都是第三方厂商,如果没有提供SPI这种实现标准,那就只有修改JAVA的源代码了,那这个弊端也是显而易见的,而有了SPI标准,SUN公司只需要提供一个播放接口,在实现播放的功能上通过ServiceLoad的方式加载服务,那么第三方只需要实现这个播放接口,再按SPI标准的约定进行打包,再放到classpath下面就OK了,没有一点代码的侵入性。

二、SPI具体约定

java spi的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader

三、实现一个自定义的SPI

1、项目结构

  • spi-interface: 是针对厂商定义的接口项目,只提供接口,不提供实现
  • spi-boy/spi-gril: 分别是两个厂商对interface的不同实现,所以他们会依赖于interface项目
  • spi-core: 是提供给用户使用的核心jar文件, 同样依赖于interface项目, 用户使用时需要引入spi-core.jar和厂商具体实现的jar
  • spi-test:用来模拟用户测试, 依赖spi-core和spi-boy/spi-gril(至少一个实现,否则会报错)

2、代码

  • spi-interface

  • spi-boy

  •  spi-gril

  • spi-core
  • 这里根据具体业务逻辑具体实现

没有找到具体实现抛出异常 b.如果发现多个实现,分别打印

  • spi-test

无厂商实现jar引入

引入spi-boy

引入spi-gril

同时引入spi-gril/spi-boy

 

四、应用场景

  1. JDBC加载不同类型的驱动
  2. SLF4J对log4j/logback的支持
  3. Spring中大量使用了SPI,比如:对servlet3.0规范对ServletContainerInitializer的实现、自动类型转换Type Conversion SPI(Converter SPI、Formatter SPI)等
  4. Dubbo中也大量使用SPI的方式实现框架的扩展, 不过它对java提供的原生SPI做了封装
  5. 更多应用场景需要大家一起去发现,或者自己使用SPI机制实现代码的解耦

参考:https://www.jianshu.com/p/46b42f7f593c

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

Java SPI机制 的相关文章

  • Netbeans 8.1 Gnome 3 GTK+ UI 字体和选项卡高度

    我刚刚在运行 GNOME 3 桌面的 Ubuntu 16 04 上安装了 NetBeans 8 1 如果可能的话 我想继续使用 IDE 的 GTK 外观和感觉 但 UI 上的字体 尤其是选项卡中的字体 太小且重叠 我尝试添加 fontsiz
  • 使用 Tabula 通过 Python 读取 pdf 时出现 Java 错误

    我已经安装了 tabula 库 用于使用 python 将 pdf 读取到 pandas 数据框中 但是当我运行代码时 import tabula df tabula read pdf sample1 pdf pages 1 我得到了例外
  • TreeMap 删除所有大于某个键的键

    在项目中 我需要删除键值大于某个键的所有对象 键类型为Date 如果重要的话 据我所知TreeMapJava中实现的是红黑树 它是一种二叉搜索树 所以我应该得到O n 删除子树时 但除了制作尾部视图并一一删除之外 我找不到任何方法可以做到这
  • Java 的支持向量机?

    我想用Java编写一个 智能监视器 它可以随时发出警报detects即将到来的性能问题 我的 Java 应用程序正在以结构化格式将数据写入日志文件
  • Thymeleaf 3 Spring 5 映射加载字符串而不是 HTML

    我正在尝试将 Spring 5 和 Thymeleaf 3 一起配置 我正在 Eclipse 上工作 我使用 全新安装 构建并使用 springboot run 运行应用程序 我已经设置了一个控制器和几个模板 但 Thymeleaf 似乎找
  • 为什么即使我的哈希码值相同,“==”也会返回 false

    我写了一个像这样的课程 public class HashCodeImpl public int hashCode return 1 public static void main String args TODO Auto generat
  • Android studio - 如何保存先前活动中选择的数据

    这是我的代码片段 这Textview充当按钮并具有Onclicklistner在他们 当cpu1000时Textview单击它会导致cpu g1000其代码如下所示的类 public class Game 1000 extends AppC
  • Runtime.exec 处理包含多个空格的参数

    我怎样才能进行以下运行 public class ExecTest public static void main String args try Notice the multiple spaces in the argument Str
  • 如何在单个查询中搜索 RealmObject 的 RealmList 字段

    假设我有一堂课 public class Company extends RealmObject private String companyId private RealmList
  • Android 无法解析日期异常

    当尝试解析发送到我的 Android 客户端的日期字符串时 我得到一个无法解析的日期 这是例外 java text ParseException 无法解析的日期 2018 09 18T00 00 00Z 位于 偏移量 19 在 java t
  • Sun 在 EDT 之外做 GUI 工作的演示?

    我正在看SplashDemo java http download oracle com javase tutorial uiswing examples misc SplashDemoProject src misc SplashDemo
  • 如何仅从 Firestore 获取最新更新的数据?

    在 Firestore 上发现任何更改时始终获取整个文档 如何只获取最近更新的数据 这是我的数据 我需要在第一次加载时在聊天中按对象顺序 例如 2018 09 17 30 40 msg和sendby 并且如果数据更新则仅获取新的msg和se
  • 将人类日期(当地时间 GMT)转​​换为日期

    我正在服务器上工作 服务器正在向我发送 GMT 本地日期的日期 例如Fri Jun 22 09 29 29 NPT 2018在字符串格式上 我将其转换为日期 如下所示 SimpleDateFormat simpleDateFormat ne
  • 如何在 ant 中为 junit 测试设置 file.encoding?

    我还没有完全完成file encoding 和 ant https stackoverflow com questions 1339352 how do i set dfile encoding within ants build xml
  • 蓝牙发送和接收文本数据

    我是 Android 开发新手 我想制作一个使用蓝牙发送和接收文本的应用程序 我得到了有关发送文本的所有内容逻辑工作 但是当我尝试在手机中测试它时 我看不到界面 这是Main Activity Code import android sup
  • 不可变的最终变量应该始终是静态的吗? [复制]

    这个问题在这里已经有答案了 在java中 如果一个变量是不可变的并且是final的 那么它应该是一个静态类变量吗 我问这个问题是因为每次类的实例使用它时创建一个新对象似乎很浪费 因为无论如何它总是相同的 Example 每次调用方法时都会创
  • hibernate 6.0.2.Final 和 spring boot 2.7.0 的entityManagerFactory bean 未配置问题

    所以最近我想升级我的 Spring Boot 项目项目的一些依赖项 特别是这些组件 雅加达 EE 9 弹簧靴2 7 休眠 6 0 2 Final 完成此操作后 所有更新和代码折射 更新将 javax 导入到 jakarta 以及一些 hib
  • Hibernate 本机查询 - char(3) 列

    我在 Oracle 中有一个表 其中列 SC CUR CODE 是 CHAR 3 当我做 Query q2 em createNativeQuery select sc cur code sc amount from sector cost
  • java 中的蓝牙 (J2SE)

    我是蓝牙新手 这就是我想做的事情 我想获取连接到我的电脑上的蓝牙的设备信息并将该信息写入文件中 我应该使用哪个 api 以及如何实现 我遇到了 bluecove 但经过几次搜索 我发现 bluecove 不能在 64 位电脑上运行 我现在应
  • Spring RESTful控制器方法改进建议

    我是 Spring REST 和 Hibernate 的新手 也就是说 我尝试组合一个企业级控制器方法 我计划将其用作未来开发的模式 您认为可以通过哪些方法来改进 我确信有很多 RequestMapping value user metho

随机推荐

  • Python深度学习-u4.1:分类和回归术语表

    分类和回归都包含很多专业术语 这些术语在机器学习领域都有确切的定义 本文对常见术语进行整理 样本 sample 或输入 input 进入模型的数据点 预测 prediction 或输出 output 从模型出来的结果 目标 target 真
  • PgSQL优化的100种方法

    1 确保数据库系统已经针对最新版本更新了所有的安全补丁 2 确保持久化数据所在的设备的 I O 操作速度非常快 3 将表的分区分布在多个磁盘上 以提高数据和索引的访问速度 4 为了确保快速数据访问 请使用恰当的索引 但不要过度依赖索引 5
  • 外卖经营小助理,快速帮你获取外卖店面经营情况

    外卖经营小助理 快速帮你获取外卖店面经营情况
  • 生产者消费者模型你知道多少

    背景 进入正题之前先说点故事 从最开始学java的那里开始 我是从08年下半年开始学Java 在 我的六年程序之路 中提到了一些 当时比较简单 每天看尚学堂的视频 对于初学者而言看视频好一些 然后写代码 比较清楚的记得马士兵讲到生产者消费者
  • linux学习书籍汇总 值得推荐的linux学习书籍

    在总结这些linux学习书籍之前 我在各个linux学习讨论群 都能看到许多新手在问关于linux学习书籍推荐这样的问题 在这里 整理了一些值得推荐的linux学习书籍 希望对新手学习linux有一定的帮助 1 嵌入式Linux C语言程序
  • 使用ElementUI在同一张表格上同时实现合并行和列单元格

    代码演示地址 https jsfiddle net Tomatoro 可以直接在代码演示地址自己尝试想要实现的效果效果图
  • 《硬件架构的艺术》笔记(二)

    时钟和复位 2 1 同步设计 2 1 1避免使用行波计数器 用触发器来驱动其他触发器的时钟输入端 一般会存在问题 由于第个触发器时钟到g的延而使第二个触发器的时钟输入产生偏 而且不能在每个时钟边沿都激活 用这种方式连接两个以上的触发器就会形
  • Altium Designer 16来自原理图/PCB的各种报错 (持续更新):

    NO1 Net xxx has only one pin 根本原因 在BGA的原理图绘制时 我一般拉出该元件的所有IO的网络 这方便利于我开发其他款板卡 同样也会因为不同板卡的需求不同而造成有些IO并没有使用到 也就是整个原理图中only
  • 软件测试的学习方法

    学习软件测试需要掌握以下几个步骤 1 了解软件测试基础知识 软件测试是指在软件开发过程中 对软件进行验证和确认 以确定其是否符合规定的需求 标准和规范 因此 学习软件测试需要先理解软件测试的定义 分类 流程等基本概念 2 学习软件测试工具
  • 读写锁的实现

    读写锁的实现 待编辑
  • STEM教育课程的发展

    STEM教育本身的定义就是跨学科的整合式教育 科创教育近几年一直是教育领域的重头戏 由机器人和3D打印引发的创新科技教育热潮一直引领着创新教育行业 细分归属STEM教育的范畴 格物斯坦小坦克来说说stem教育课程的发展 STEM教育是全球许
  • 深入解析中间件之-Canal

    canal 阿里巴巴mysql数据库binlog的增量订阅 消费组件 MySQL binlog MySQL主从复制 mysql服务端修改配置并重启 1 2 3 4 5 6 7 8 9 10 11 12 vi etc my cnf mysql
  • Bonita实现的BPM应用系统

    多个领域的组织已经从Bonita的BPM解决方案中受益 用于改进它们的业务流程 世界各地的很多机构在它们的系统中已经成功布署了Bonita 1 Government of the Canary Islands 电子政务系统的BPM Boni
  • Optional int parameter 'folderId' is not present but cannot be translated into a null value due to b

    错误信息 严重 Servlet service for servlet controller in context with path gxbms threw exception Request processing failed nest
  • ungui中mainform以及login窗体的背景设置

    1 打开mainmodule窗体 2 设置mainmodule的background属性 3 设置mainmodule窗体的loginbackground属性 结果
  • 25个恶意JavaScript 库通过NPM官方包仓库分发

    聚焦源代码安全 网罗国内外最新资讯 编译 代码卫士 专栏 供应链安全 数字化时代 软件无处不在 软件如同社会中的 虚拟人 已经成为支撑社会正常运转的最基本元素之一 软件的安全性问题也正在成为当今社会的根本性 基础性问题 随着软件产业的快速发
  • Windows中通过命令行新建文件夹、新建文件

    进大厂 身价翻倍的法宝来了 主讲内容 docker kubernetes 云原生技术 大数据架构 分布式微服务 自动化测试 运维 腾讯课堂 点击进入 网易课堂 点击进入 7月1号 7月29号 8折优惠 7月1号 7月29号 8折优惠 7月1
  • 补码的作用

    补码的作用 避免零在二进制中的歧义 另一个好处就是方便运算 所有运算都能用加法运算器来实现 不再需要减法运算器 其实在计算机中 所有的减法操作都被转化为加法操作 如果想要深入研究 可以看看计算机组成原理 举个简单的例子 正数的补码和反码 原
  • 《Learning CUDA Programming》读书笔记(三)

    CUDA occupancy 一般等于 Active Thread Blocks per Multiprocessor Max Threads per Multiprocessor 分子是用户kernel和GPU硬件条件共同决定的 分母完全
  • Java SPI机制

    一 SPI机制简介 SPI的全名为Service Provider Interface java spi机制的思想 系统里抽象的各个模块 往往有很多不同的实现方案 在面向的对象的设计里 一般推荐模块之间基于接口编程 模块之间不对实现类进行硬