大家好,我是三友~~
今天来跟大家聊一聊JAVA、Spring、Dubbo三者SPI机制的原理和区别 。
其实我之前写过一篇类似的文章,但是这篇文章主要是剖析dubbo的SPI机制的源码,中间只是简单地介绍了一下Java、Spring的SPI机制,并没有进行深入,所以本篇就来深入聊一聊这三者的原理和区别 。
什么是SPISPI全称为Service Provider Interface,是一种动态替换发现的机制,一种解耦非常优秀的思想,SPI可以很灵活的让接口和实现分离,让api提供者只提供接口,第三方来实现,然后可以使用配置文件的方式来实现替换或者扩展,在框架中比较常见,提高框架的可扩展性 。
简单来说SPI是一种非常优秀的设计思想,它的核心就是解耦、方便扩展 。
Java SPI机制--ServiceLoaderServiceLoader是Java提供的一种简单的SPI机制的实现,Java的SPI实现约定了以下两件事:
- 文件必须放在META-INF/services/目录底下
- 文件名必须为接口的全限定名,内容为接口实现的全限定名
来个demo第一步,需要一个接口以及他的实现类
public interface LoadBalance {}public class RandomLoadBalance implements LoadBalance{}
第二步,在META-INF/services/目录创建一个文件名LoadBalance全限定名的文件,文件内容为RandomLoadBalance的全限定名测试类:
public class ServiceLoaderDemo {public static void main(String[] args) {ServiceLoader<LoadBalance> loadBalanceServiceLoader = ServiceLoader.load(LoadBalance.class);Iterator<LoadBalance> iterator = loadBalanceServiceLoader.iterator();while (iterator.hasNext()) {LoadBalance loadBalance = iterator.next();System.out.println("获取到负载均衡策略:" + loadBalance);}}}
测试结果:文章插图
此时就成功获取到了实现 。
在实际的框架设计中,上面这段测试代码其实是框架作者写到框架内部的,而对于框架的使用者来说,要想自定义LoadBalance实现,嵌入到框架,仅仅只需要写接口的实现和spi文件即可 。
实现原理如下是ServiceLoader中一段核心代码
文章插图
首先获取一个fullName,其实就是META-INF/services/接口的全限定名
然后通过ClassLoader获取到资源,其实就是接口的全限定名文件对应的资源,然后交给parse方法解析资源
文章插图
parse方法其实就是通过IO流读取文件的内容,这样就可以获取到接口的实现的全限定名
再后面其实就是通过反射实例化对象,这里就不展示了 。
所以其实不难发现ServiceLoader实现原理比较简单,总结起来就是通过IO流读取META-INF/services/接口的全限定名文件的内容,然后反射实例化对象 。
优缺点由于Java的SPI机制实现的比较简单,所以他也有一些缺点 。
第一点就是浪费资源,虽然例子中只有一个实现类,但是实际情况下可能会有很多实现类,而Java的SPI会一股脑全进行实例化,但是这些实现了不一定都用得着,所以就会白白浪费资源 。
第二点就是无法对区分具体的实现,也就是这么多实现类,到底该用哪个实现呢?如果要判断具体使用哪个,只能依靠接口本身的设计,比如接口可以设计为一个策略接口,又或者接口可以设计带有优先级的,但是不论怎样设计,框架作者都得写代码进行判断 。
所以总得来说就是ServiceLoader无法做到按需加载或者按需获取某个具体的实现 。
使用场景虽然说ServiceLoader可能有些缺点,但是还是有使用场景的,比如说:
- 不需要选择具体的实现,每个被加载的实现都需要被用到
- 虽然需要选择具体的实现,但是可以通过对接口的设计来解决
Spring的SPI机制的约定如下:
- 配置文件必须在META-INF/目录下,文件名必须为spring.factories
- 文件内容为键值对,一个键可以有多个值,只需要用逗号分割就行,同时键值都需要是类的全限定名,键和值可以没有任何类与类之间的关系,当然也可以有实现的关系 。
推荐阅读
- 静态路由or动态路由,一个例子说明白!
- 贾玲|真被热巴说中了!曝贾玲秘密生子,范丞丞冲上热搜榜一
- 阿里p6是什么级别(p6级别工资标准)
- 闭口是什么意思(如何去闭口)
- 厂长为什么叫7酱(lpl解说鼓鼓多人运动)
- 裁剪视频用什么软件(电商视频剪辑用什么软件)
- 拜灶神要说什么 拜灶神要怎样说话
- 西装裤配什么鞋子(西装裤怎么搭配上衣)
- 谛听为什么不说出真相(谛听为啥听出来真假不说)
- 每个手指戴戒指的含义怎么说 每个手指戴戒指的含义