学习ShardingSphere前置知识
学习ShardingSphere前置准备知识
一. SPI
SPI(Service Provider Interface)是一种Java的扩展机制,用于实现组件之间的松耦合。在SPI模型中,服务提供者(Service Provider)定义了一组接口,而服务的使用者可以根据接口编写代码。服务提供者则提供了接口的具体实现,这些实现可以被动态加载和替换。
下面是对SPI的理解:
1.接口定义: SPI的核心是一个接口,定义了一组规范或协议,以描述一种服务。以java.sql.Driver为例
2.服务提供者: 服务提供者是实现了接口的具体类。这些类通常通过在类路径中的META-INF/services目录下提供一个配置文件来注册自己。

其中在配置文件中的全类名为服务提供者,它实现了定义的接口

3.服务加载: 使用者通过查找和加载在类路径中的META-INF/services目录下的配置文件,获取服务提供者的实现类。Java的ServiceLoader类通常用于加载这些服务提供者。
使用ServiceLoader.load()进行服务发现与对应的配置文件的类进行加载
4.动态替换: 由于服务提供者的实现是通过配置文件注册的,因此可以在不修改使用者代码的情况下动态替换服务提供者。这使得系统更加灵活,并且可以在运行时适应不同的实现。
5.松耦合: SPI实现了松耦合的设计,允许开发者通过接口定义和服务提供者实现分离。这样,服务提供者可以独立于使用者进行开发、测试和部署。
二. ServiceLoader.load()
public final class ServiceLoader<S>implements Iterable<S>
{@CallerSensitivepublic static <S> ServiceLoader<S> load(Class<S> service) {ClassLoader cl = Thread.currentThread().getContextClassLoader();return new ServiceLoader<>(Reflection.getCallerClass(), service, cl);}// 实现Iterable接口必须要重写的方法 主要通过spi发现服务提供者,并进行驱动注册,加载public Iterator<S> iterator() {// create lookup iterator if neededif (lookupIterator1 == null) {lookupIterator1 = newLookupIterator();}return new Iterator<S>() {// record reload countfinal int expectedReloadCount = ServiceLoader.this.reloadCount;// index into the cached providers listint index;/*** Throws ConcurrentModificationException if the list of cached* providers has been cleared by reload.*/private void checkReloadCount() {if (ServiceLoader.this.reloadCount != expectedReloadCount)throw new ConcurrentModificationException();}@Overridepublic boolean hasNext() {checkReloadCount();if (index < instantiatedProviders.size())return true;return lookupIterator1.hasNext();}@Overridepublic S next() {checkReloadCount();S next;if (index < instantiatedProviders.size()) {next = instantiatedProviders.get(index);} else {next = lookupIterator1.next().get();instantiatedProviders.add(next);}index++;return next;}};}
}
它实现了Iterable接口,可以增强for循环,在遍历的时候进行相应的处理,接下来先熟悉下Iterable接口的使用
2. Iterable
public interface Iterable<T> {Iterator<T> iterator();default void forEach(Consumer<? super T> var1) {Objects.requireNonNull(var1);Iterator var2 = this.iterator();while(var2.hasNext()) {Object var3 = var2.next();var1.accept(var3);}}default Spliterator<T> spliterator() {return Spliterators.spliteratorUnknownSize(this.iterator(), 0);}
}
其中default方法为默认方法,使用default关键字为接口添加默认方法是为了在不破坏现有实现的情况下,为接口添加新的方法。
不需要强制实现
以下为是实现Iterable接口的例子,必须重写iterator()方法,类表明它可以被迭代(iterable),即可以被用于增强型 for 循环。
public class TestIterable<T> implements Iterable<T>{private List<T> list;public TestIterable(List<T> list){this.list = list;}@Overridepublic Iterator<T> iterator() {return list.iterator();}
}
下面分析下ServiceLoader.load入口出,在java.sql.DriverManager类内部调用,如下代码
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();try {// 此处调用Iterator实现的hasNext方法,查找spi接口while (driversIterator.hasNext()) {driversIterator.next();}
} catch (Throwable t) {// Do nothing
}
return null;
}
以上代码通过对Iterator的实现,查找到对应路径下的文件,该路径即是spi的配置文件,文件里配置的是定义接口的实现类,
然后对该实现类进行类加载
/*** Loads and returns the next provider class.*/private Class<?> nextProviderClass() {if (configs == null) {try {//static final String PREFIX = "META-INF/services/";String fullName = PREFIX + service.getName();if (loader == null) {configs = ClassLoader.getSystemResources(fullName);} else if (loader == ClassLoaders.platformClassLoader()) {// The platform classloader doesn't have a class path,// but the boot loader might.if (BootLoader.hasClassPath()) {configs = BootLoader.findResources(fullName);} else {configs = Collections.emptyEnumeration();}} else {configs = loader.getResources(fullName);}} catch (IOException x) {fail(service, "Error locating configuration files", x);}}while ((pending == null) || !pending.hasNext()) {if (!configs.hasMoreElements()) {return null;}pending = parse(configs.nextElement());}String cn = pending.next();try {return Class.forName(cn, false, loader);} catch (ClassNotFoundException x) {fail(service, "Provider " + cn + " not found");return null;}}
ServiceLoader.load静态方法是 Java 提供的一种用于加载服务提供者实现的机制。
它是 Java SPI(Service Provider Interface)的一部分,用于在运行时动态加载服务接口的实现类。
具体来说,ServiceLoader.load 的作用是:
加载服务接口的实现类:通过 ServiceLoader.load(ServiceType.class),可以加载与指定服务接口 ServiceType 相关的所有实现类。这些实现类必须位于 META-INF/services/ 目录下的以服务接口全限定名为名称的配置文件中。
返回一个 ServiceLoader 对象:ServiceLoader.load 返回一个 ServiceLoader 对象,通过这个对象,你可以遍历加载到的所有服务提供者的实例。
public class TestSpi {public static void main(String[] args) {ServiceLoader<HumanTestSPI> loadHumanTestSPI = ServiceLoader.load(HumanTestSPI.class);//遍历加载到的所有服务提供者的实例。for (HumanTestSPI humanTestSPI:loadHumanTestSPI){humanTestSPI.speak();}}
}

以上为学习ShardingSphere前置知识,后面会用到大量的spi接口.
相关文章:
学习ShardingSphere前置知识
学习ShardingSphere前置准备知识 一. SPI SPI(Service Provider Interface)是一种Java的扩展机制,用于实现组件之间的松耦合。在SPI模型中,服务提供者(Service Provider)定义了一组接口,而服务…...
读书笔记-《数据结构与算法》-摘要3[选择排序]
选择排序 核心:不断地选择剩余元素中的最小者。 找到数组中最小元素并将其和数组第一个元素交换位置。在剩下的元素中找到最小元素并将其与数组第二个元素交换,直至整个数组排序。 性质: 比较次数(N-1)(N-2)(N-3)…21~N^2/2交换次数N运行…...
Arduino驱动MLX90614红外测温传感器(温湿度传感器)
目录 1、传感器特性 2、测量方法 3、硬件原理图 4、控制器和传感器连线图...
Ubuntu上传文件到SMB共享文件夹
0. 前言 公司有一些数据共享文件夹,平时可以把开发的重要文件放到上面备份。本人开发使用ubuntu系统,共享文件夹是windows的形式,想通过命令的方式,方便快捷,还可shell脚本自动化。 1. 安装挂载库 sudo apt-get upd…...
【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区
文章目录 一、重定向1.什么是重定向2.dup2 系统调用3.理解输入重定向、输出重定向和追加重定向4.简易shell完整实现 二、理解linux下一切皆文件三、缓冲区1.为什么要有缓冲区2.缓冲区的刷新策略3.缓冲区的位置4.实现一个简易的C语言缓冲区5.内核缓冲区 一、重定向 1.什么是重定…...
RINEX介绍
一、RINEX是什么 Receiver Independent Exchange Format (RINEX) 是一种用于存储、交换和处理全球定位系统 (GPS) 接收机观测数据的标准化文件格式。RINEX 格式由国际电信联盟 (ITU) 和国际GPS服务 (IGS) 组织共同开发和维护。它提供了一种通用的数据格式,使得不同…...
ROS-ROS通信机制-服务通信
文章目录 一、服务通信基本知识二、自定义srv三、C实现四、Python实现 一、服务通信基本知识 服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求…...
chown和chmod
chown和chmod都是在Linux和Unix系统中用于设置文件和文件夹权限的命令,但它们的功能和用途有所不同。 功能:chown主要用于修改文件或文件夹的所有者和所属组,而chmod则主要用于修改文件或文件夹的读写执行权限。用途:如果想要授权…...
【GPU】linux 安装、卸载 nvidia 显卡驱动、cuda 的官方文档、推荐方式(runfile)
文章目录 1. 显卡驱动1.1. 各版本下载地址1.2. 各版本文档地址1.3. 安装、卸载方式 2. CUDA2.1. 各版本下载地址2.2. 各版本文档地址2.3. 安装、卸载方式2.4. 多版本 CUDA 切换方式 1. 显卡驱动 1.1. 各版本下载地址 https://www.nvidia.com/Download/Find.aspx?langzh-cn 1…...
6页手写笔记总结信号与系统常考知识大题知识点
题型一 判断系统特性题型二 求系统卷积题型三 求三大变换正反变换题型四 求全响应题型五 已知微分方程求系统传递函数题型六 已知系统的传递函数求微分方程题型七 画出系统的零极点图,并判断系统的因果性和稳定性 (笔记适合快速复习,可能会有…...
Qt-QSplitter正确设置比例
简短版本: splitter->setSizes({1000, 2000}); // 这个值至少跟像素值设置的一样大,或者更大,例如x10倍详细版本: setSizes 官方介绍如下: Sets the child widgets’ respective sizes to the values given in the…...
一篇吃透大厂面试题,2024找工作一帆风顺。
🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…...
【1day】用友 U8 Cloud系统TaskTreeQuery接口SQL注入漏洞学习
注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现...
华为快应用中自定义Slider效果
文章目录 一、前言二、实现代码三、参考链接 一、前言 在华为快应用中官方提供了<slider>控件,但是这个控件的限制比较多,比如滑块无法自定义,所以这里进行下自定义,自己修改样式。 二、实现代码 整体效果如下: 源码如下…...
C语言每日一题(43)旋转链表
力扣 61 旋转链表 题目描述 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 示例 1: 输入:head [1,2,3,4,5], k 2 输出:[4,5,1,2,3]示例 2: 输入:head [0,1,2], …...
CCF计算机软件能力认证考试—202209-1如此编码
题目背景 某次测验后,顿顿老师在黑板上留下了一串数字 23333 便飘然而去。凝望着这个神秘数字,小 P 同学不禁陷入了沉思…… 题目描述 已知某次测验包含 � 道单项选择题,其中第 � 题(1≤�≤&…...
Ubuntu18.04安装Ipopt-3.12.8流程
本文主要介绍在Ubuntu18.04中安装Ipopt库的流程,及过程报错的解决方法,已经有很多关于Ipopt安装的博客,但经过我的测试,很多都失效了,经过探索,找到可流畅的安装Ipopt的方法,总结成本篇博客。 …...
linux 内核同步互斥技术之信号量
信号量 信号量允许多个进程同时进入临界区,大多数情况下只允许一个进程进入临界区,把信号量的计数值设置为 1,即二值信号量,这种信号量称为互斥信号量。可允许多个锁持有者。 和自旋锁相比,信号量适合保护比较长的临界…...
交通强国添力量 无人机巡航为何备受期待?
在高速建设交通强国的过程中,交通运输部海事局计划完善“陆海空天”一体化水上交通运输安全保障体系。无人机巡航系统将在提升海事船舶监管和水上搜救能力方面发挥关键作用,以构建更为全面的监管体系。尽管已初步建立了海事监管体系,但仍存在…...
【PID学习笔记 6 】控制系统的性能指标之二
写在前面 上文介绍了控制系统的稳态与动态、过渡过程、阶跃响应以及阶跃信号作用下过渡过程的四种形式。本文紧接上文,首先总结过渡过程的分类,然后介绍控制系统的性能评价,最后重点介绍控制系统性能指标中的单项指标。 一、过渡过程的分类…...
R语言实战:用sf和ggplot2绘制带比例尺和指北针的专业地图(附完整代码)
R语言地理信息可视化实战:从数据到专业地图的完整指南 地理信息数据可视化是科研和商业分析中不可或缺的一环。无论是环境监测、城市规划还是流行病学研究,将空间数据转化为直观的地图都能极大提升数据洞察力。本文将手把手教你使用R语言中的sf和ggplot2…...
【FastAPI 2.0流式AI响应实战指南】:3步接入、5大避坑点、性能提升300%的工业级落地方案
第一章:FastAPI 2.0流式AI响应的核心演进与工业价值FastAPI 2.0 将原生流式响应能力从实验性支持升级为一级公民特性,彻底重构了高吞吐 AI 服务的构建范式。其核心在于深度整合 ASGI 3.0 的异步流语义与 Starlette 的 StreamingResponse 基础设施&#x…...
Wan2.2-I2V-A14B效果展示:10秒1080P高清视频生成作品集(RTX4090D实测)
Wan2.2-I2V-A14B效果展示:10秒1080P高清视频生成作品集(RTX4090D实测) 1. 专业级视频生成效果惊艳亮相 Wan2.2-I2V-A14B文生视频模型在RTX4090D显卡上的表现令人印象深刻。经过深度优化的私有部署镜像,能够稳定生成10秒1080P高清…...
键盘魔法师:如何用VIA让机械键盘“听懂”你的心声?
键盘魔法师:如何用VIA让机械键盘“听懂”你的心声? 【免费下载链接】releases 项目地址: https://gitcode.com/gh_mirrors/re/releases 想象一下这样的场景:深夜加班,手指在键盘上飞舞,突然想用一个快捷键调出…...
GHelper:华硕笔记本性能调校神器,让你的ROG设备焕发新生
GHelper:华硕笔记本性能调校神器,让你的ROG设备焕发新生 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other mod…...
Matplotlib 函数手册:3D 绘图
Matplotlib 的三维绘图并不是一套独立系统,而是在原有 Figure、Axes 与子图机制上的扩展。三维图仍沿用标题、坐标轴标签与布局调整等基本框架,只是绘图对象从二维平面延伸到了三维空间。在较新的 Matplotlib 版本中,只要使用 projection3d 创…...
新手零失败指南:基于快马平台生成win10安装openclaw的交互式学习应用
最近在Windows 10上折腾OpenClaw的安装,作为新手真的踩了不少坑。环境配置报错、依赖冲突、权限问题...每次遇到错误都要花大量时间搜索解决方案。后来发现用InsCode(快马)平台可以快速生成带交互指导的安装程序,终于找到了适合新手的打开方式。这里把完…...
Kook Zimage真实幻想Turbo部署教程:免conda环境纯pip安装方案
Kook Zimage真实幻想Turbo部署教程:免conda环境纯pip安装方案 1. 项目简介 Kook Zimage真实幻想Turbo是一款专为个人GPU设计的轻量化幻想风格文生图系统。它基于Z-Image-Turbo官方极速文生图底座,通过特殊技术融合了专属的幻想风格模型权重,…...
【专栏一:AI基础01】-【一张图讲清楚什么是大模型】
专栏一:AI基础入门-什么是大模型?大模型通俗解释大模型通俗解释 我们可以把大模型想象成一个超级大脑: 它在诞生之初,会先阅读人类海量的文字、知识、书籍、网页、对话,把所有信息消化成一套庞大的数学规律和语言逻辑&…...
5个鲜为人知的开源工具性能优化技巧:让WaveTools效率提升100%
5个鲜为人知的开源工具性能优化技巧:让WaveTools效率提升100% 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 你是否遇到过开源工具运行卡顿、启动缓慢的问题?是否在处理大型项目时…...
