SPI机制详解

SPI机制详解

什么是SPI机制?

SPI:Service Provider Interface,中文直译:服务提供者接口,它通过在ClassPath路径下的META-INF/service文件夹中查找文件,并自动加载文件里所定义的类
在这里插入图片描述

在面向对象的设计原则中,一般推荐模块之间基于接口编程,通常情况下调用方模块是不会感知到被调用方模块的内部具体实现。一旦代码里面涉及具体实现类,就违反了开闭原则。如果需要替换一种实现,就需要修改代码。

为了实现在模块装配的时候不用在程序里面动态指明,这就需要一种服务发现机制。Java SPI 就是提供了这样一个机制:为某个接口寻找服务实现的机制。这有点类似 IoC 的思想,将装配的控制权移交到了程序之外。

SPI机制的出现是为了解决什么问题?

举个经典的栗子,在后端开发中,不可避免的就是通过JDBC去连接数据库,但是不同的数据库有不同的驱动,MySQL有MySQL的驱动,Oracle有Oracle的驱动,但是它们都实现了JDBC接口

在这里插入图片描述

假如现在有个需求,项目原来使用的是MySQL作为数据库,但是现在要替换成Oracle数据库,怎么实现?

去项目中手动去改变Driver的实现类?

Driver driver = new OracleDriverImpl();

太不优雅了,太不体面了🤣

有没有一种方法能动态替换实现类,如果我现在导入的Jar包是MySQL的驱动我就将Driver的实现类定义为MySQL的驱动包,导入的Jar包是Oracle的驱动我就将Driver的实现类定义为Oracle的驱动包?

诶,Java开发者定义了这样一个规则,在项目的ClassPath目录中创建META-INF/Services目录,在这里面创建以接口名为文件名,内容为实现类的全限定名的一个文件;

在这里插入图片描述

再通过IO的方式获取到所有的全限定名,如果存在MySQL数据库的驱动,那么calssNameList = [“com.mysql.cj.jdbc.Driver”]

以下代码为伪代码,在java.util.ServiceLoader#load(Class clazz) 完成了spi 的实现,具体的思想跟下面的流程类似,感兴趣的可以去看一看

在这里插入图片描述

SPI这种方式可以很好解决不同框架之间的拓展问题,可以同时兼容同一个接口的多个实现类;

SPI机制的变种

学过SpringBoot的童鞋们都知道自动装配绝对是SpringBoot的大招,它可以将外部框架的配置类动态的加载到我们IOC的容器中;其实它的思想与SPI机制非常类似;

以mybatis-plus为例

在这里插入图片描述

问题:因为mybatis-plus的ClassPath与我们的项目路径不同,肯定是不能通过扫描注解的方式注入到IOC中

那么SpringBoot定义了一个机制,如果这些框架想将自己的配置类注入到使用者的IOC中,你可以在框架包的ClassPath下创建一个META-INF目录,在这个目录中创建一个spring.factories文件

在这里插入图片描述

在这里插入图片描述

在SpringBoot项目启动时,会加载所有Jar包下META-INF/spring.factories文件,根据org.springframework.boot.autoconfigure.EnableAutoConfiguration后面的全限定类名,通过反射将这个类加载到IOC的容器中

这样就达到了项目与框架之间的解耦,在项目不需要手动去将这些框架的配置类加载到IOC容器中;

除了SpringBoot的自动装配体现了SPI的思想,还有例如Dubbo、Slf4j等等

总结
  1. SPI机制能够使接口与具体的实现类解耦,可以根据实际的业务情况启用或替换具体组件
  2. SPI机制为很多框架的拓展提供了可能
  3. SPI机制更多的是一种思想

如果觉得本篇文章对于您有帮助,可否点个小赞😺;篇幅较长建议收藏🫠;关注一手等待后续更新更多干货🚀

参考视频:https://www.bilibili.com/video/BV1E44y1N7Nk/?spm_id_from=333.337.search-card.all.click&vd_source=835177d483a47b8fcf9934ddad59626a

参考文章:https://javaguide.cn/java/basis/spi.html

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

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

相关文章

Device Tree (二) - dtb格式

dtb作为二进制文件被加载到内存中,然后由内核读取并进行解析,如果对dtb文件的格式不了解,那么在看设备树解析相关的内核代码时将会寸步难行,而阅读源代码才是了解设备树最好的方式,所以,如果需要更透彻的了…

【数据结构】哈希表(Hash Table)

文章目录 一:哈希表(Hash Table)1.1 简介1.2 可以将算法思想分为两个部分1.3 相关术语1.4 性质 二:哈希冲突2.1 什么是哈希冲突2.2 为何要避免哈希冲突2.3 如何避免哈希冲突2.4 如何减少哈希冲突2.4.1 直接地址法2.4.1 除留余数法…

C语言入门学习 --- 7.结构体

文章目录 第七章结构体1.结构体的声明1.1结构的基础知识1.2结构的声明1.3结构成员的类型1.4结构体变量的定义和初始化 2.结构体成员的访问2.1结构体变量访问成员2.2结构体指针访问指向变量的成员 3.结构体传参配套练习: 第七章结构体 1.结构体类型的声明 2.结构体初…

工具篇--分布式定时任务springBoot 整合 elasticjob使用(3)

文章目录 前言一、Springboot 整合:1.1 引入jar:1.2 配置zookeeper 注册中心:1.3 定义job 业务类:1.4 job 注册到zookeeper:1.5 项目启动:1.5.1 zookeeper 注册中心实例:1.5.2 任务执行日志输出…

Ubuntu 14.04:PaddleOCR基于PaddleServing的在线服务化部署(失败)

一、 二、安装 注: 安装 PaddleOCR 2.3 。 因为 PaddleOCR 2.4 的 推荐环境 PaddlePaddle > 2.1.2。 https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.4/doc/doc_ch/environment.md 安装前的环境准备 在使用Paddle Serving之前,需要完…

flink重温笔记(十五): flinkSQL 顶层 API ——实时数据流转化为SQL表的操作

Flink学习笔记 前言:今天是学习 flink 的第 15 天啦!学习了 flinkSQL 基础入门,主要是解决大数据领域数据处理采用表的方式,而不是写复杂代码逻辑,学会了如何初始化环境,鹅湖将流数据转化为表数据&#xff…

数据结构和算法:复杂度分析

算法效率评估 时间效率:算法运行速度的快慢。 空间效率:算法占用内存空间的大小。 效率评估方法主要分为两种:实际测试、理论估算 实际测试问题: 1.难以排除测试环境的干扰因素。 硬件配置会影响算法的性能。需要在各种机器上进…

Web 常用的 扩展开发框架

当谈到提升浏览器功能和用户体验时,浏览器扩展成了一股强大的力量,备受用户青睐。在众多的Web扩展开发框架中,WXT和Plasmo凭借其丰富的工具和特性,以及简化的开发流程,成为开发者们的首选。在本文中,我们将…

【嵌入式DIY实例】-DIY锂电池电压检测表

DIY锂电池电压检测表 文章目录 DIY锂电池电压检测表1、直流电压检测传感器介绍2、硬件准备3、代码实现4、OLED显示在电子应用中,通常需要使用到电池,电源管理是必不可少的部分。本文将详细介绍如何使用一个0-25V的直流电压传感器来检测锂电池的电压。 1、直流电压检测传感器介…

数据分析-Pandas如何画自相关图

数据分析-Pandas如何画自相关图 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据表&#x…

C#,文字排版的折行问题(Word-wrap problem)的算法与源代码

1、英文的折行问题 给定一个单词序列,以及一行中可以输入的字符数限制(线宽)。 在给定的顺序中放置换行符,以便打印整齐。 假设每个单词的长度小于线宽。 像MS word这样的文字处理程序负责放置换行符。 这个想法是要有平衡的线条。…

Android kotlin开启协程的几种方式

在Android开发中,使用Kotlin协程(coroutines)可以极大地简化异步编程的复杂性,提高代码的可读性和可维护性。以下是几种在Android Kotlin项目中开启协程的常用方式: 1. 使用GlobalScope.launch 这是最简单直接的开启…

2024.3.12-408学习笔记-C-C++

1、引用& #include <stdio.h>void modify_pointer(int* &p1, int* q1) {p1 q1; }int main() {int* p NULL;int i 10;int* q &i;modify_pointer(p, q);printf("after modify_pointer *p %d\n", *p);//after modify_pointer *p 10return 0; }…

专业140+总分430+西南交通大学924信号与系统考研经验电子信息与通信工程,真题,大纲,参考书

今年报考西南交通大学&#xff0c;考研分数专业课924信号与系统140&#xff0c;总分430&#xff0c;各门分数都还是比较均衡&#xff0c;经过一年的复习&#xff0c;有得有失&#xff0c;总结一下自己的复习经历&#xff0c;希望给大家有点帮助&#xff0c;在复习中做的更好&am…

Android 使用AIDL HAL

生成的目录结构 以audioControl 为例: 首先编写的是aidl文件。 其文件目录结构是:── android │ └── hardware │ └── automotive │ └── audiocontrol │ ├── AudioFocusChange.aidl │ ├── AudioGainConf…

LeetCode 1409.查询带键的排列

给定一个正整数数组 queries &#xff0c;其取值范围在 1 到 m 之间。 请你根据以下规则按顺序处理所有 queries[i]&#xff08;从 i0 到 iqueries.length-1&#xff09;&#xff1a; 首先&#xff0c;你有一个排列 P[1,2,3,…,m]。 对于当前的 i &#xff0c;找到 queries[i]…

Sklearn基本算法

sklearn&#xff08;Scikit-learn&#xff09;是一个非常流行的Python机器学习库&#xff0c;它提供了一系列简单高效的算法和工具&#xff0c;适用于各种机器学习任务。下面是一些基本的机器学习算法类别和对应的常用算法&#xff1a; 分类算法 逻辑回归&#xff08;Logisti…

请列出60个Python热点面试题目

以下是60个Python热点面试题目&#xff0c;涵盖了Python基础知识、数据类型、面向对象编程、函数和模块、文件操作、错误处理、并发编程、数据库操作、网络编程、框架和库等多个方面&#xff1a; 谈谈你对Python语言的理解&#xff0c;它有哪些主要特点&#xff1f;Python有哪…

钉钉平台“智”领宠物界,开启萌宠智能新时代!

在当前数字化转型的浪潮中&#xff0c;钉钉用便捷的数字化解决方案推动了宠物业界的智能升级。一家宠物用品公司采用无雀科技数字化管理系统&#xff0c;与钉钉平台结合&#xff0c;解决了小型企业普遍存在的财务管理不清晰、业务流程不规范、客户信息核对繁琐等痛点问题。 针对…

html5cssjs代码 012 我的像册

html5&css&js代码 012 我的像册 一、代码二、解释 这段HTML代码定义了一个简单的网页&#xff0c;实现了一个简洁、响应式的图片相册页面。 一、代码 <!DOCTYPE html> <html lang"zh-cn"> <head><title>编程笔记 html5&css&…