2024年某厂面试:如何优雅使用 SPI 机制,写得太好了

文末

我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档

  • 第一个要分享给大家的就是算法和数据结构

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 第二个就是数据库的高频知识点与性能优化

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 第三个则是并发编程(72个知识点学习)

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

看到这里相信就遇到过绝大多数技术同学都会遇到的一个问题,那就是 认为自己会了,实际情况呢?不一定。所以,学习一门技术,一定要多看几遍,尝试去理解记忆。千万不要看一遍之后,眼高手低认为技术 so easy,然后隔十天半个月就啥都不记的

某厂面试:如何优雅使用 SPI 机制

继续回过头来说说今天的主角:SPI。首先回答这么一个问题,什么是 SPI 机制

SPI 全称为 Service Provider Interface,是一种服务发现机制。为了被第三方实现或扩展的 API,它可以用于实现框架扩展或组件替换

SPI 机制本质是将 接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载文件中的实现类,这样运行时可以动态的为接口替换实现类

看文字描述介绍总是枯燥无味且空洞的。简单一点来说,就是你在 META-INF/services 下面定义个文件,然后通过一个特殊的类加载器,启动的时候加载你定义文件中的类,这样就能扩展原有框架的功能

就这么简单,那可能有读者会问:我不定义在 META-INF/services 下面行不行?就想定义在别的地方

某厂面试:如何优雅使用 SPI 机制

不行滴,请遏制住这么危险的想法,人家怎么定义你就怎么实现。这是 JDK 规定好的配置路径,你随便定义,类加载器怎么知道去哪里加载

某厂面试:如何优雅使用 SPI 机制

看到这个 PREFIX 常量之后,想法比较活跃的小伙子不知道清醒点了么。简单画张图来描述下 SPI 的运行机制

某厂面试:如何优雅使用 SPI 机制

有点 SPI 基础的同学看到图之后应该又开始自信了,这不就是我之前看过的那玩意么?是的,技术还是那个技术,可以继续往下看看,有没有自己不知道的

为什么要有 SPI

=========

了解一项技术的前提,一定要知道它为了解决什么样的痛点而存在,JDK 作者也不会没屁事加点代码玩

引入了 SPI 机制后,服务接口与服务实现就会达成分离的状态,可以实现 解耦以及程序可扩展机制。服务提供者(比如 springboot starter)提供出 SPI 接口后,客户端(平常的 springboot 项目)就可以通过本地注册的形式,将实现类注册到服务端,轻松实现可插拔

数据加密举例

======

以实际项目举个例子,就拿 sharding-jdbc 数据加密模块来说,sharding-jdbc 本身支持 AES 和 MD5 两种加密方式。但是,如果客户端不想用内置的两种加密,偏偏想用 RSA 算法呢?难道每加一种算法,sharding-jdbc 就要发个版本么

某厂面试:如何优雅使用 SPI 机制

sharding-jdbc 可不会这么干,首先提供出 Encryptor 加密接口,并引入 SPI 的机制,做到服务接口与服务实现分离的效果。如果客户端想要使用新的加密算法,只需要在客户端项目 META-INF/services 目录下定义接口的全限定名称文件,并在文件内写上加密实现类的全限定名,就像这样式的

某厂面试:如何优雅使用 SPI 机制

通过 SPI 的方式,就可以将客户端提供的加密算法加载到 sharding-jdbc 加密规则中,这样就可以在项目运行中选择自定义算法来对数据进行加密存储

通过 sharding-jdbc 的例子,可以很好的看出来,上面提到的 SPI 优点,都体现了出来

  1. 客户端(自己的项目)提供了服务端(sharding-jdbc)的接口自定义实现,但是与服务端状态分离,只有在客户端提供了自定义接口实现时才会加载,其它并没有关联;客户端的新增或删除实现类不会影响服务端

  2. 如果客户端不想要 RSA 算法,又想要使用内置的 AES 算法,那么可以随时删掉实现类,可扩展性强,插件化架构

配合实际案例理解 SPI 是不是很简单。为了防止有些小伙伴没有理解 sharding-jdbc 的例子,这里再举一个真实的例子

对象存储举例

======

假如你是一家集团公司里做公共架构开发的(可以把这个集团想大一点,几百家子公司的那种 ️ ),领导给你安排了个开发任务,需要你开发一个对象存储服务,让其它业务线的团队使用,统一集团内部的对象存储

OK,开发诉求明白了,这个时候就该想想怎么去完成这个需求(主要想给领导留个好印象,升官发财 ing…)。首先应该考虑的是要兼容多套对象存储供应商,比如阿里 OSS、腾讯 COS、华为云 OBS,最基本的三连对吧

高高兴兴的封装了个 starter,告诉领导封装完成了,然后就下发到各项目组去用了。但是这个时候其中一个子公司负责人告诉你,说他们之前用的七牛云 Kodo

某厂面试:如何优雅使用 SPI 机制

心态炸了呀,难道要给他再适配一个七牛云么?万一适配完这个,又一位大哥说项目自建 HDFS 咋整

聊到这,大家就明白了吧,SPI 的场景可不就出现了么。就是身为服务提供者,在你无法形成绝对规范强制的时候,“放权” 往往是比较明智的选择,适当让客户端去自定义实现

这个时候,回过头想一想最初的一个问题。为什么 sharding-jdbc 不多实现几套算法,而是提供出一个 SPI 接口呢

因为开发者明白,不论提供多少接口,总有个别用户因各方面因素导致的个性化需求。个性化这个事情是追摸不透的,就像 女生的心思一样,永远不知道在想什么…(重点都加黑加粗了,剩下的全靠自己领悟)

某厂面试:如何优雅使用 SPI 机制

实战讲解

====

都说到这了,不来个实战,感觉有点说不过去。吹过的牛逼,负责到底!就实现上面说的统一对象存储服务的代码

最简单的对象存储,只需要两个接口就可以实现功能,分别是 上传和下载

某厂面试:如何优雅使用 SPI 机制

定义好上传、下载接口后,我们就要考虑,如何让客户端项目可以选择底层的对象存储服务器,以及如何通过 SPI 的方式将客户端自定义的文件存储组件加载到服务端

我们可以定义个对象存储容器,存放可以使用的对象存储服务,然后再 使用 SPI 的机制加载客户端自定义组件放到容器。对象存储服务放到容器中自然需要一个标识,那么就需要给文件接口加一个获取类型接口

某厂面试:如何优雅使用 SPI 机制

定义好了接口,就要写具体的代码了。我们为 对象存储服务提供出一个对外的门面,所有访问对象存储的服务,必须访问门面对象进行文件的上传下载操作

下面这段代码将 对象服务 bean 存储至容器,并提供根据客户端的自定义配置,选择合适的对象存储服务

代码里用到的关键字 var 是 lombok 的注解,可以自动识别对象类型

某厂面试:如何优雅使用 SPI 机制

因为是个示例 demo,所以将获取对象存储和具体的上传、下载耦合在了一起,如果小伙伴有类似需求,一定要将不同行为拆分开,类职责尽量单一些

这段代码整体逻辑不算复杂,所以也有点自信回头,就没跑单元测试,不过问题应该不大。解释一下其中具体逻辑:

  1. FileServiceFactory 大家可以理解为文件服务对外的统一访问入口。实现了 spirng 初始化的一个接口,可以在 bean 初始化时进行代码逻辑操作

  2. bean 初始化时,通过 ServiceLoader 类加载器负责加载对象存储接口,这样就能加载到客户端存放到 META-INF/services 中的自定义对象存储实现

  3. 获取到自定义对象存储后,和服务端本身自带的对象存储一起存放至容器中,这样就可以根据项目中的 fileStoreType 获取对应的服务了

最后

最后,强调几点:

  • 1. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
  • 2. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
  • 3. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

链图片转存中…(img-FWdyFAZC-1715263153097)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值