dubbo spi和java spi的原理和区别

spi是什么?

SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。 SPI的作用就是为这些被扩展的API寻找服务实现。

使用场景

调用者根据实际使用需要,启用、扩展、或者替换框架的实现策略,如下使用场景
1.JDBC加载不同类型数据库的驱动
2.slf4j需要替换不同日志组件

java 的spi

在这里插入图片描述


ServiceLoader<ISayHello>
serviceLoader=ServiceLoader.load(ISayHello.class);
        System.out.println("Java SPI");
        serviceLoader.forEach(ISayHello::say);
ServiceLoader 获取当前线程的类加载器 根据类加载器构建ServiceLoader对象,构建对象完成,不加载任何类 ServiceLoader ServiceLoader.load流程
ServiceLoader LayerLookupIterator stack 调用foreach方法(获取迭代器,构建迭代器对象LayerLookupIterator) 迭代开始。 调用迭代器next() 获取配置文件中当前类的列表,并且放入stack中(此操作只执行一次) loop [: 循环加载配置类] stack弹出一个是个实现类路径,进行加载类,并且实例化,此时就是所谓懒加载 loop [循环获取特定的类,并且实例化] 迭代完成。 ServiceLoader LayerLookupIterator stack ServiceLoader迭代流程

核心逻辑:
从上图可以看出,核心逻辑就是使用stack特性完成迭代,先把加载所有类入stack,然后调用next时候一个出栈,直到空为止则遍历完成
主要的核心对象有:
ServiceLoader:服务加载器,spi核心入口类,加载在指定的类型而且在配置文件当中配置的类,并且实例化(实例交给LayerLookupIterator迭代器做)。
LayerLookupIterator:翻译过来,懒加载迭代器,ServiceLoader内置的默认是实现的迭代器。从源码分析得处,就是在调用LayerLookupIterator对服务进行遍历时候会装载配置文件类,并且实例化。

Java SPI 不足之处:

1.虽然java spi是懒加载形式,但是获取某种实例的时候,是通过迭代器形式获取,所以依然加载所有配置文件中的所有实现类的实例。
2.不能按需加载。Java SPI在加载扩展点的时候,会一次性加载所有可用的扩展点,很多是不需要的,会浪费系统资源。
3.获取某个实现类的方式不够灵活,只能通过 Iterator 形式获取,不能根据某种类型(策略标识)来获取对应的实现类。

dubbo 的spi

讲完Java SPI的不足,那么dubbo 的spi肯定有他的优点之处,不然不可能费那么大的劲重复造轮子。
相比Java的spi,dubbo做了以下改进:
1.开闭原则,dubbo预制好很多spi地方,无需进行源码修改即可进行拓展。(这个不算改进)
2.延时加载,按需加载,可以一次性只加载自己所需要的实现。(大大改进)
3.增加对IOC容器的支持和AOP的支持,简单说就是支持Spring最强功能,可以将dubbo的spi实例注入到其他bean

dubbo的spi是如何实现按需加载?

其实原理很简单,就是在配置文件做了手脚,如下
在这里插入图片描述
因为做了key和value的配置映射,就可以对实现类进行分类。获取的实现类代码如下。

ExtensionLoader<ISayHello> extensionLoader =
           ExtensionLoader.getExtensionLoader(ISayHello.class);
        ISayHello optimusPrime = extensionLoader.getExtension("jason");
        optimusPrime.say();
        ISayHello bumblebee = extensionLoader.getExtension("jerry");
        bumblebee.say();
总结:

1.java的spi和dubbo的spi都是给开发者需要对源码进行二次开发或者二次拓展进行预留一些口子,符合代码的开闭原则。
2.dubbo的spi对java的spi进行的一些适当改进,可以按需加载,同时增加对spring容器的一些支持,这样方便类似spring全家桶开发代码极大方便。
3.两者实现原理都很简单,dubbo的按需加载从本质上来讲对实现类进行二级分类,从更小级别按需加载。

参考:
Java SPI 与 Dubbo SPI 有什么区别?
面试大咖说:Dubbo SPI 和 Java SPI 区别

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值