美团到店一面,SPI 机制了解过么?最重要的部分是什么?

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产Star破10w的开源项目,前端包括管理后台、微信小程序,后端支持单体、微服务架构

RBAC权限、数据权限、SaaS多租户、商城、支付、工作流、大屏报表、ERP、CRMAI大模型、IoT物联网等功能:

  • 多模块:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • 微服务:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK17/21+SpringBoot3、JDK8/11+Spring Boot2双版本 

来源:飞天小牛肉


什么是 SPI

SPI 全称为 (Service Provider Interface) ,是 JDK 内置的一种服务提供发现机制,为使用者提供了服务扩展点,使用者无需修改源码就可以自定义服务实现,简单理解就是为服务的具体实现提供了一个可插拔机制。

比如你的项目中

SPI 的Java doc 如下,感兴趣的小伙伴可以阅读下:

A service is a well-known set of interfaces and (usually abstract) classes. A service provider is a specific implementation of a service. The classes in a provider typically implement the interfaces and subclass the classes defined in the service itself. Service providers can be installed in an implementation of the Java platform in the form of extensions, that is, jar files placed into any of the usual extension directories. Providers can also be made available by adding them to the application's class path or by some other platform-specific means

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

Java SPI 实战

设想这样一个场景,你写了一个框架要给别人用,你内置了一些序列化的方法,但是总有些使用者会有自己的特殊的序列化逻辑,这时候你就可以把序列化方法的接口通过 SPI 暴露出去,交给使用者来自定义实现。这样,使用者就可以接入自己自定义的序列化方法。

如下,我们定义一个序列化接口:

重点在这里的 load 方法,我们通过 ServiceLoader.load() 来加载指定的 Serializer 实现类列表,然后使用第一个实现类。具体底层原理咱们先按下不表。

再随便写两个实现类实现这个接口:

再建立一个以暴露出去的接口的全路径为命名的文件,比如我这里的就是 com.example.draft.Serializer,注意这个文件一定要放在 resources/META-INF/services 下面

文件的内容也很简单,就是你想使用的 Serializer 接口具体实现类的全路径,多个实现类之间直接换行就可以,比如:

至此,SPI 机制全部完成,我们来测试下:

我们通过 load 方法加载了配置文件中配置的第一个实现类(也就是 SerializerImpl2),并调用了它的 serialize 方法,输出的内容是:

以上,是单体项目的示范,你可以把这个项目打成 jar 包,别人导入这个 jar 包的时候,同样通过上述配置文件的方法,来自定义暴露出来的 SPI 接口。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

Java SPI 原理

不难理解,SPI 的重点就是 ServiceLoader,看源码,我们发现这个类是一个 final 类型的,所以是不可被继承修改,同时它实现了 Iterable 接口,方便后续我们能够通过迭代的方式得到对应的服务实现。

再往下,可以看到一个熟悉的常量定义 META-INF/services/

重点看 load 方法:

简单来说,load 的核心逻辑就是使用指定的类型和当前线程绑定的类加载器(ClassLoader)实例化了一个 LazyIterator 对象,并清除 Provider 缓存。

ServiceLoader 实现了 Iterable 接口的方法后,具有了迭代的能力,在 iterator() 方法被调用时,首先会在 ServiceLoader 的 Provider 缓存中进行查找,如果缓存中没有命中那么则在 LazyIterator 中进行查找:

在调用 LazyIterator 时,具体实现如下:

没有什么太复杂的逻辑,我这里只截取了关键代码,核心逻辑就 3 点:

  1. 到预先定义的地方(META-INF/service/+类名)去找配置文件

  2. 解析配置文件拿到全类名

  3. 通过反射获取实现类


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
该数据集通过合成方式模拟了多种发动机在运行过程中的传感器监测数据,旨在构建一个用于机械系统故障检测的基准资源,特别适用于汽车领域的诊断分析。数据按固定时间间隔采集,涵盖了发动机性能指标、异常状态以及工作模式等多维度信息。 时间戳:数据类型为日期时间,记录了每个数据点的采集时刻。序列起始于2024年12月24日10:00,并以5分钟为间隔持续生成,体现了对发动机运行状态的连续监测。 温度(摄氏度):以浮点数形式记录发动机的温度读数。其数值范围通常处于60至120摄氏度之间,反映了发动机在常规工况下的典型温度区间。 转速(转/分钟):以浮点数表示发动机曲轴的旋转速度。该参数在1000至4000转/分钟的范围内随机生成,符合多数发动机在正常运转时的转速特征。 燃油效率(公里/升):浮点型变量,用于衡量发动机的燃料利用效能,即每升燃料所能支持的行驶里程。其取值范围设定在15至30公里/升之间。 振动_X、振动_Y、振动_Z:这三个浮点数列分别记录了发动机在三维空间坐标系中各轴向的振动强度。测量值标准化至0到1的标度,较高的数值通常暗示存在异常振动,可能与潜在的机械故障相关。 扭矩(牛·米):以浮点数表征发动机输出的旋转力矩,数值区间为50至200牛·米,体现了发动机的负载能力。 功率输出(千瓦):浮点型变量,描述发动机单位时间内做功的速率,取值范围为20至100千瓦。 故障状态:整型分类变量,用于标识发动机的异常程度,共分为四个等级:0代表正常状态,1表示轻微故障,2对应中等故障,3指示严重故障。该列作为分类任务的目标变量,支持基于传感器数据预测故障等级。 运行模式:字符串类型变量,描述发动机当前的工作状态,主要包括:怠速(发动机运转但无负载)、巡航(发动机在常规负载下平稳运行)、重载(发动机承受高负荷或高压工况)。 数据集整体包含1000条记录,每条记录对应特定时刻的发动机性能快照。其中故障状态涵盖从正常到严重故障的四级分类,有助于训练模型实现故障预测与诊断。所有数据均为合成生成,旨在模拟真实的发动机性能变化与典型故障场景,所包含的温度、转速、燃油效率、振动、扭矩及功率输出等关键传感指标,均为影响发动机故障判定的重要因素。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值