SPI机制详解

news2024/11/25 22:41:21

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.coloradmin.cn/o/1511895.html

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

相关文章

Linux中文件的权限

我们首先需要明白,权限 用户角色 文件的权限属性 一、拥有者、所属组和other(用户角色) 以文件file1为例 第一个箭头所指处即是文件的拥有者,拥有者为zz 第二个箭头所指处即使文件的所属组,所属组为zz 除去拥有者…

利用高分五号02星高光谱数据进行地物识别

高分五号02星搭载了一台60公里幅宽、330谱段、30米分辨率的可见短波红外高光谱相机(AHSI),可见近红外(400~1000nm)和短波红外光谱(1000~2500nm)分辨率分别达到5纳米和10纳米。单看参数性能优越&…

spring boot使用mybatisplus访问mysql的配置流程

网上教程大多教人新建一个带对应组件的项目,本文记录如何在一个已有springboot2.x项目中,配置使用mybatisplus来访问mysql。包括使用wrapper和自己写mapper.xml的自定义函数两种和数据库交互的方式。 关于项目的创建,参考创建springboot 2.x…

PFMEA的输入输出和特殊特性

DFMEA輸入:技术条件、市场需求 DFMEA輸出:产品特殊特性、试验、样件CPPFMEA輸入:过往经验、流程图、DPMEA PFMEA輸出:CP、过程特殊特性、SIP、SOP1. PFMEA的输入包括:()过程流程图、DFMEA 、图样…

基于springboot+vue的线上教育系统(源码+论文)

目录 前言 一、功能设计 二、功能实现 三、库表设计 四、论文 前言 现在大家的生活方式正在被计算机的发展慢慢改变着,学习方式也逐渐由书本走向荧幕,我认为这并不是不能避免的,但说实话,现在的生活方式与以往相比有太大的改变,人们的娱乐方式不仅仅…

P4513 小白逛公园 习题笔记(线段树维护区间最大连续子段和)

传送门https://www.luogu.com.cn/problem/P4513本文参考了董晓老师的博客 这道题着实想了很长时间(新手),只能想到一个O(mn)的dp普通写法,那么遇上区间修改问题改怎么操作呢。答案很明显,线段树…

微服务day01 -- SpringCloud01 -- (Eureka , Ribbon , Nacos)

介绍微服务 1.认识微服务(p1-p5) 随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢? 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的稻田虫害检测系统详解(深度学习+Python代码+UI界面+训练数据集)

摘要:本篇文章深入探讨了如何利用深度学习技术开发一个用于检测稻田虫害的系统,并且分享了完整的实现过程和资源代码下载。该系统采用了当前的YOLOv8、YOLOv7、YOLOv6、YOLOv5算法,对其进行了性能对比,包括mAP、F1 Score等关键指标…

redis中通用命令以及key过期策略

通用命令 exists 判断某个key是否存在。 exists key时间复杂度:O(1) 返回值:key 存在的个数。 del 删除指定的 key,可以一次删除一个或者多个。 del key时间复杂度:O(1) 返回值:删除掉的 key 的个数。 expire…

根据索引策略对elasticsearch中的索引进行管理(附带图文教程)

前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 一. 索引生命周期简介 想要了解更多可以看 : 索引生命周期 1.1 索引生命周期五种阶段 (1)Hot…

C++开发基础——类模板

一,基础定义 类模板是用来生成类的蓝图,是一种创建类的方式,同一套类模板可以生成很多种不同的类。 编译器基于类模板生成的每个类被称为类模板的实例。 第一次使用模板类型声明变量时,会创建类模板的一个实例, 以后…

YOLOv5改进 | 注意力篇 | 利用YOLO-Face提出的SEAM注意力机制优化物体遮挡检测(附代码 + 修改教程)

一、本文介绍 本文给大家带来的改进机制是由YOLO-Face提出能够改善物体遮挡检测的注意力机制SEAM,SEAM(Spatially Enhanced Attention Module)注意力网络模块旨在补偿被遮挡面部的响应损失,通过增强未遮挡面部的响应来实现这一目…

el-Switch 开关二次确认

前言 最近在做毕设,有个需求是点击按钮控制用户的状态是否禁用,就看到element有个switch组件可以改造一下,就上网看了一下,结果为了这个效果忙活了很久。。。所以说记录一下,让大家少踩坑。 前置条件 先看完我的需求再…

Eclipse安装springboot

Eclipse免费,套件丰富,代码开源,功能强大…推荐! 1 下载eclipse: https://www.eclipse.org/downloads/download.php?file/technology/epp/downloads/release/2023-12/R/eclipse-jee-2023-12-R-win32-x86_64.zip 2 安装Spring框…

图论(蓝桥杯 C++ 题目 代码 注解)

目录 迪杰斯特拉模板(用来求一个点出发到其它点的最短距离): 克鲁斯卡尔模板(用来求最小生成树): 题目一(蓝桥王国): 题目二(随机数据下的最短路径&#…

Hadoop学习2:完全分布集群搭建

文章目录 Fully-Distributed Operation(完全分布模式) 重点机器环境同步集群规划配置文件修改以及同步步骤0:下面其他步骤涉及修改配置以这里为准(要不然部署使用过程会有很多问题)通用配置(三台节点机器&a…

社交革命的引领者:探索Facebook如何改变我们的生活方式

1.数字社交的兴起 随着互联网的普及,社交媒体成为我们日常生活的重要组成部分。Facebook作为其中的先驱,从最初的社交网络演变成了一个拥有数十亿用户的全球化平台。它不仅改变了我们与世界互动的方式,还深刻影响了我们的社交习惯、人际关系以…

华为机考:HJ102 字符统计

华为机考&#xff1a;HJ102 字符统计 描述 方法1 先将所有字符计算数量&#xff0c;在对比其中字符的assic码 #include<iostream> #include<vector> #include<algorithm> #include<string> using namespace std; bool cmp(pair<char, int> a,…

C++ std::list的merge()使用与分析

看到《C标准库第2版》对list::merge()的相关介绍&#xff0c;令我有点迷糊&#xff0c;特意敲代码验了一下不同情况的调用结果。 《C标准库第2版》对list::merge()的相关介绍 list::merge()定义 merge()的作用就是将两个list合并在一起&#xff0c;函数有2个版本&#xff1a;…

数字图像处理-空间滤波

空间滤波 空域滤波基础 – 离散卷积的边缘效应 平滑空间滤波器 # -*- coding: utf-8 -*- # Author: Huazhong Yang # Email: cjdxyhz163.com # Time : 2024/3/7 20:26import cv2 import numpy as np# 读取图像 image cv2.imread(a1.png)# 应用高斯滤波 # 第二个参数是高斯…