Java SPI介绍

SPI

Java SPI : Service Provider Interface

是Java平台提供的一种机制,用于动态的加载和扩展功能的机制,它为框架和库提供了一种松耦合的扩展方式,核心是解耦。

例如JDBC驱动,日志框架,等应用,它为开发者提供了一种灵活的,可插拔的扩展机制,使得使用更加方便灵活,更改配置即可。

SPI整体机制图

请添加图片描述

SPI和API区别?

API 是用于定义和提供功能接口的一种方式;

而 SPI 是一种用于动态加载和扩展功能的机制。

SPI接口位于调用方包中:

接口位于调用方中,而实现在独立的包之中。

API接口位于实现方包中:

接口和实现均位于一个包中。

SPI 代码实现

  1. 先创建一个接口

    package com.junfeng.spi;
    
    public interface Logger {
        void log(String msg);
    }
    
    
  2. 实现接口

    console实现:

    package com.junfeng.spi;
    
    public class ConsoleLogger implements Logger {
        @Override
        public void log(String msg) {
            System.out.println("console sys logger:" + msg);
        }
    }
    
    

    file实现:

    package com.junfeng.spi;
    
    public class FileLogger implements Logger {
        @Override
        public void log(String msg) {
            System.out.println("file sys logger:" + msg);
        }
    }
    
  3. 配置

    创建配置文件:为每个提供者创建一个配置文件,指定提供者的实现类名。

    META-INF/services/ 目录下创建文件 com.junfeng.spi.Logger,其中 com.junfeng.spi.LoggerLogger 接口的完全限定名,内容如下:

    com.junfeng.spi.ConsoleLogger
    com.junfeng.spi.FileLogger
    
  4. 调用

    在这个示例中,ServiceLoader.load(Logger.class) 用于加载 Logger 接口的实现提供者,然后通过遍历加载的提供者,调用其 log 方法输出日志。

package com.junfeng.spi;

import java.util.ServiceLoader;

public class Test {

    public static void main(String[] args) {
        // 加载 Logger 接口的实现
        ServiceLoader<Logger> loggerLoader = ServiceLoader.load(Logger.class);
        // 遍历并使用实现提供者
        for (Logger logger : loggerLoader) {
            logger.log("hello");
        }
    }
}

原理

SPI 机制的底层原理是基于 Java 的标准类加载和反射机制。

有兴趣的看下Class.forName,里面使用到了反射方法Class.forName()加载类对象。

SPI优缺点

优点:

  1. 松耦合和可扩展性:SPI 机制可以实现插件化的架构,将接口和实现彻底解耦,使得框架和应用程序更易于扩展和维护。通过添加新的实现提供者,可以在不修改代码的情况下扩展功能。
  2. 动态加载和发现:SPI 允许在运行时动态加载实现提供者,使得框架能够根据配置文件自动发现和加载新的功能模块,从而实现了更大的灵活性。
  3. 无需修改源代码:使用 SPI,开发人员可以将接口和实现分开,避免了在框架源代码中引入大量的条件判断,使得框架更加清晰和可维护。
  4. 分离关注点:SPI 机制允许框架关注于核心功能,而将特定的实现细节留给实现提供者来处理,提高了代码的模块化和可理解性。

缺点:

  1. 没有版本管理:SPI 机制本身不提供强大的版本控制机制,当不同版本的提供者实现并存时,可能会导致不可预测的行为。
  2. 没有依赖管理:SPI 机制不具备管理依赖关系的能力,这意味着实现提供者在开发时需要确保依赖的库和版本是正确的。
  3. 不适用于复杂多实现场景:SPI 适用于一对一的接口和实现关系,当存在复杂的多实现关系时,可能需要更高级的机制来管理和调度实现。
  4. 运行时的性能开销:SPI 机制在运行时需要进行实现提供者的查找和加载,这会带来一些性能开销,尤其在大规模应用中可能会有所感知。
  5. 不适合对稳定性要求较高的场景:SPI 机制的动态性可能会增加系统的复杂性,对于对稳定性要求较高的场景,需要更严格的测试和控制。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux——基础IO(1)

目录 0. 文件先前理解 1. C文件接口 1.1 写文件 1.2 读文件 1.3 输出信息到显示器 1.4 总结 and stdin & stdout & stderr 2. 系统调用文件I/O 2.1 系统接口使用示例 2.2 接口介绍 2.3 open函数返回值 3. 文件描述符fd及重定向 3.1 0 & 1 & 2 3.2…

记录--前端重新部署如何通知用户

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 1. 场景 前端构建完上线&#xff0c;用户还停留还在老页面&#xff0c;用户不知道网页重新部署了&#xff0c;跳转页面的时候有时候js连接hash变了导致报错跳不过去&#xff0c;并且用户体验不到新功能…

SAP Fiori 问题收集

事务代码篇 启动工作台&#xff1a;/N/UI2/FLP 错误日志&#xff1a; /n/IWFND/ERROR_LOG 服务清单&#xff1a; /n/IWFND/MAINT_SERVICE 创建语义对象&#xff1a;/N/UI2/SEMOBJ 创建目录&#xff1a;/N/UI2/FLPD_CONF&#xff08;cross-client&#xff09;或 /N/UI2…

【ES】笔记-箭头函数的实践于应用场景

箭头函数的实践于应用场景 需求-1 点击 div 2s后颜色变成[粉色]从数组中返回偶数的元素 需求-1 点击 div 2s后颜色变成[粉色] html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport…

uniapp之当你问起“tab方法触发时eventchange也跟着触发了咋办”时

我相信没有大佬会在这个问题上卡两个小时吧&#xff0c;记下来大家就当看个乐子了。 当时问题就是&#xff0c;点击tab头切换的时候&#xff0c;作为tab滑动事件的eventchange同时触发了&#xff0c;使得接口请求了两次 大概是没睡好&#xff0c;我当时脑子老想着怎么阻止它冒…

怎么系统的学习机器学习、深度学习?当然是看书了

目录 前言 内容简介 学完本书&#xff0c;你将能够 作者简介 本书目录 京东自购链接 前言 近年来&#xff0c;机器学习方法凭借其理解海量数据和自主决策的能力&#xff0c;已在医疗保健、 机器人、生物学、物理学、大众消费和互联网服务等行业得到了广泛的应用。自从Ale…

【GPT-3 】创建能写博客的AI工具

一、说明 如何使用OpenAI API&#xff0c;GPT-3和Python创建AI博客写作工具。 在本教程中&#xff0c;我们将从 OpenAI API 中断的地方继续&#xff0c;并创建我们自己的 AI 版权工具&#xff0c;我们可以使用它使用 GPT-3 人工智能 &#xff08;AI&#xff09; API 创建独特的…

uniapp 微信小程序 封装公共的请求js(api版本)

一、新建api文件夹 在项目目录下创建api文件夹&#xff0c;内放files跟index.js文件夹&#xff0c;files文件夹内放每个页面对应的js请求接口 1、index.js /*** api接口的统一出口*/ const api {}; const requireComponent require.context(./files, false, /\.js$/) requi…

4个简化IT服务台任务的ChatGPT功能

最近几个月&#xff0c;ChatGPT 风靡全球&#xff0c;这是一个 AI 聊天机器人&#xff0c;使用户能够生成脚本、文章、锻炼图表等。这项技术在各行各业都有无穷无尽的应用&#xff0c;在本文中&#xff0c;我们将研究这种现代技术如何帮助服务台团队增强服务交付和客户体验。 什…

林【2019】

关键字&#xff1a; 哈夫曼树权值最小、哈夫曼编码、邻接矩阵时间复杂度、二叉树后序遍历、二叉排序树最差时间复杂度、非连通无向图顶点数&#xff08;完全图&#xff09;、带双亲的孩子链表、平衡二叉树调整、AOE网关键路径 一、判断 二、单选 三、填空 四、应用题 五、算…

Blazor 简单组件(0):简单介绍

文章目录 前言说明环境安装 前言 Blazor 这个技术还是比较新&#xff0c;相关的UI组件还在完善&#xff0c;我这里提供一下我个人的组件开发。 说明 本UI组件是基于BootstrapBlazor(以下简称BB)开发。 BootstrapBlazor 文档 环境安装 C#小轮子&#xff1a;Visual Studio自…

第一百二十三天学习记录:C++提高:STL-vector容器(下)(黑马教学视频)

vector插入和删除 功能描述&#xff1a; 对vector容器进行插入、删除操作 函数原型&#xff1a; push_back(ele); //尾部插入元素ele pop_back(); //删除最后一个元素 insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele insert(const_iterator pos, int cou…

(el-switch)操作(不使用 ts):Element-plus 中 Switch 将默认值修改为 “true“ 与 “false“(字符串)来控制开关

Ⅰ、Element-plus 提供的 Switch 开关组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供 Switch 组件情况&#xff1a; 其一、Element-ui 自提供的 Switch 代码情况为(示例的代码)&#xff1a; // Element-plus 自提供的代码&#xff1a; // 此时是使用了 ts 语言环…

山东布谷科技直播系统源码热点分析:不同芯片实现高质量编码与渲染视频的GPU加速功能

在现代科技的迅猛发展下&#xff0c;直播系统源码平台被开发搭建出来&#xff0c;为人们的生活方式带来了很大的改变&#xff0c;直播系统源码平台的好友、短视频、直播、社区等功能让很多人越来越热衷于去在平台上刷视频、看直播、分享生活。用户的喜爱也督促了直播系统源码平…

Vue3 Props组件简单应用(子组件获取父组件数据)

去官网学习→Props | Vue.js 运行示例&#xff1a; 代码&#xff1a;App.vue <template><img alt"Vue logo" src"./assets/logo.png"><!-- 传递数据 key value--><Mycomponent :dataTest"content" :dataNmub&…

Java类型转换

总是忘&#xff0c;总是记混&#xff0c;气气气&#xff01; 基本类型 4整型、2浮点型、1布尔、1字符 关键字大小取值范围包装类型byte8-27~27-1Byteshort16-215~215-1Shortint32-231~231-1Integerlong64-263~263-1Longfloat323.4e-38~3.4e38Floatdouble641.7e-38~1.7e38Dou…

linux Ubuntu 更新镜像源、安装sudo、nvtop、tmux

1.更换镜像源 vi ~/.pip/pip.conf在打开的文件中输入: pip.conf [global] index-url https://pypi.tuna.tsinghua.edu.cn/simple按下:wq保存并退出。 2.安装nvtop 如果输入指令apt install nvtop报错&#xff1a; E: Unable to locate package nvtop 需要更新一下apt&a…

tomcat多实例与动静分离

多实例&#xff1a; 在一台服务器上配置多台tomcat服务 配置 tomcat 环境变量 修改 tomcat2 中的 server.xml 文件&#xff0c;要求各 tomcat 实例配置不能有重复的端口号 vim /usr/local/tomcat/tomcat2/conf/server.xml<Server port"8006" shutdown"SHUT…

数据结构:堆的实现(C实现)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》 文章目录 一、堆二、实现思路1. 结构的定义2. 堆的构建 (HeapInit)3. 堆的销毁 (HeapDestroy)4. 堆的插入 (HeapPush)5. 堆的删除 (HeapPop)6. 取堆顶的数据 (HeapTop)7. 堆的数据个数 (HeapSize…

CentOS7安装Maven详细教程

&#x1f60a; 作者&#xff1a; Eric &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_47316183?typeblog &#x1f389; 主题&#xff1a;CentOS7安装Maven详细教程 ⏱️ 创作时间&#xff1a; 2023年08月06日 第一步&#xff1a;上传或下载安装包&#x…