聊聊Java的SPI机制

什么是SPI

SPI:Service Provider Interface

官方定义:直译过来是服务提供者接口,学名为服务发现机制,它通过在ClassPath 路径下的META-INF/services文件夹中查找文件,并自动加载文件里所定义的类。

应用场景

JDBC

不同的驱动由不同数据库厂商实现,但因为java中提供驱动的是一个接口,不可以直接实例化,所以要想实例化接口,必须要知道这个接口的全限定名。然后通过反射或其他方式来构建实例进而调用具体的方法。

image

于是java开发者们想了这样一个方法在项目下的ClassPath目录中创建META-INF/services文件夹,并在这个创建以接口名为文件夹、以类全限定名为文件内容的文件。然后就可以通过IO获取到所有的全限定名。

image

SpringBoot自动装配

问题

SpringBoot会将当前包及其子包下的bean注入到ioc中,但此时如果其他框架需要将bean注入到ioc中,因为包名是不相同的,所以不能通过扫描注入,而且在注入的过程中要和项目尽可能的解耦。

image

所以SpringBoot规定了在ClassPath目录下META-INF文件夹中可以定义spring.factories的文件,在项目启动时会遍历所有jar包下的spring.factories文件这样就可以将spring.factories文件中定义的类加载到ioc中。

Dubbo

自定义类加载器 +策略模式

Dubbo中SPI的基本流程与使用

Dubbo中AOP的源码实现

Dubbo中的依赖注入的源码实现

Dubbo中的Adaptive扩展点的源码实现5. Dubbo中的Activate扩展点的源码实现

image

总结

SPI机制能够使接口与具体的实现类解耦,

可以根据实际的业务情况启用或替换具体组件。

SPI机制为很多框架的扩展提供了可能。

SPI机制更多的是一种思想。

参考:https://www.bilibili.com/video/BV1E44y1N7Nk

题外话

那么策略模式和 SPI 机制到底有什么区别呢?

如果从代码接入的级别来看,策略模式还是在原有项目中进行代码修改,只不过它不会修改原有类中的代码,而是新建了一个类。而 SPI 机制则是不会修改原有项目中的代码,其会新建一个项目,最终以 Jar 包引入的方式代码。

从这一点来看,无论策略模式还是 SPI 机制,他们都是将修改与原来的代码隔离开来,从而避免新增代码对原有代码的影响。但策略模式是类层次上的隔离,而 SPI 机制则是项目框架级别的隔离。

从应用领域来说,策略模式更多应用在业务领域,即业务代码书写以及业务代码重构。而 SPI 机制更多则是用于框架的设计领域,通过 SPI 机制提供的灵活性,让框架拥有良好的插件特性,便于扩展。

总结一下,策略模式与 SPI 机制有下面几点异同:

  • 从设计思想来看。策略模式和 SPI 机制其思想是类似的,都是通过一定的设计隔离变化的部分,从而让原有部分更加稳定。
  • 从隔离级别来看。策略模式的隔离是类级别的隔离,而 SPI 机制是项目级别的隔离。
  • 从应用领域来看。策略模式更多用在业务代码书写,SPI 机制更多用于框架的设计。
posted @ 2022-04-23 14:26  飞飞很要强  阅读(102)  评论(0编辑  收藏  举报