「某大厂二面」聊聊Java中的SPI机制

SPI service provider interface的简写

SPI是什么

SPI主要解决的还是耦合问题。我们知道面向接口编程是很好的编程方式。

举一个简单的例子

         假设有一天你一不小心成为了你们组的组长,这时候经理要求你开发一个对象存储服务,统一一下公司内部的云存储服务,首先市面上的云存储有好多家,例如阿里的OSS,腾讯的COS,华为的OBS等等。

        你加班加点的把你知道的云存储服务开发完了,第二天给别的组讲解你的服务,这是另一个组的负责人说我们之前都用七牛云Kodo,另一个我们也是一直用的HDFS,这时候你就懵了,那我们还有给他们都加上吗?当然不用!

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

简单举例

 首先你需要了解 ServiceLoader这个类

  • resources下定义文件如图

    文件名:接口
    内容:具体实现类
    「某大厂二面」聊聊Java中的SPI机制_第1张图片
  • 接口及实现类
    「某大厂二面」聊聊Java中的SPI机制_第2张图片

         services下的文件内容

  •  简单测试
    「某大厂二面」聊聊Java中的SPI机制_第3张图片

「某大厂二面」聊聊Java中的SPI机制_第4张图片

总结

上面说了很多关于 SPI 机制的优点以及应用场景,这里总结下关键内容

  1. SPI 机制优势就是解耦。将接口的定义以及具体业务实现分离,而不是和业务端全部耦合在一端。可以实现 运行时根据业务实际场景启用或者替换具体组件

  2. SPI 机制的场景就是 没有统一实现标准的业务场景。一般就是,服务端有标准的接口,但是没有统一的实现,需要业务方提供其具体实现。比如说 JDBC 的 java.sql.Driver 接口和不同云厂商提供的数据库实现包

每个事物都是既有优点,同时也伴随着缺点。要从两个方面去看,不能总盯着一方面。这里说一下 SPI 机制的缺点

  1. 不能按需加载。虽然 ServiceLoader 做了延迟加载,但是只能通过遍历的方式全部获取。如果其中某些实现类很耗时,而且你也不需要加载它,那么就形成了资源浪费

  2. 获取某个实现类的方式不够灵活,只能通过迭代器的形式获取。这两点可以参考 Dubbo SPI 实现方式进行业务优化

文章通过图文并茂的方式帮助大家重新梳理了一遍 SPI 的场景、优势和缺点,看完文章后相信大家对 SPI 机制有了更深入的认识

梳理出 SPI 的场景以及优势后,小伙伴最好再去 Debug 源代码,这样会大家对 SPI 的实现才能更加清楚。只有对一个知识点真正掌握,才不至于事后很快遗忘 

你可能感兴趣的:(Java,分布式,java)