手写dubbo 6-SPI(预热篇)
条评论博客中代码地址:https://github.com/farliu/farpc.git
本章不讲述其他SPI博文所说的细节,SPI博文实在太多了。但你可以在本章了解到SPI作用以及其他博文中没有解释详细的地方。继续看上面这张图,SPI其实不属于图中的任何一个环节。但是它对dubbo尤为重要,也是非常值得一说的内容。
dubbo选择SPI背景及作用
在众多dubbo源码解析的博文,都会将SPI做重点来解说,可见它对dubbo多么重要。那么我们先来了解一下SPI的背景。我在官方的quick start中找到这样一句话。
大概的意思就是告诉我们,dubbo可以只依赖JDK,不依赖于任何三方库就可以运行。这其实也是dubbo设计者的一个夙求。
聊dubbo的SPI之前,我们先聊聊spring,spring最值得吹捧的功能就是IOC。而IOC自然也是整个开发历程的必然产物,因为当众多框架(MVC、ORM)诞生后,肯定是需要有这样一个东西来将多个框架粘合在一次的。而IOC就是这样一个粘合剂,它作为粘合剂实现的方案就是将大家的bean管理在一起,以此达到相互调用。
那么dubbo设计者不想让dubbo依赖任何第三方库就能运行,难道它就没有IOC这样的需求吗?自然是有的。那么dubbo选择的解决方案就是使用SPI,基于jdk原生的SPI帮助dubbo创建类的对象。那么我们暂且可以将SPI简单的理解为它帮助dubbo初始化对象。
SPI的作用,我们暂且这么理解了。那么dubbo用它来做了什么呢?我们模拟一下场景,dubbo作为一款优秀的框架,肯定需要适配各样的场景,例如:
- 注册中心,用户可以选择zookeeper、redis…
- rpc协议,用户可以选择netty、http…
- 负载均衡,用户需要根据自己硬件配置选择负载均衡策略
这就到了SPI的登场的时候了。dubbo对于需要提供扩展的接口,例如我们上一章的ILoadbalance,使用SPI根据用户的配置初始化对应的实现类。而程序在运行时只需要关注调用对应的接口就行了。
补充众多SPI博文中没有讲述的
说SPI,众多博客中都会提到API,简单的说,api是给使用者使用的,spi是给拓展者使用的。这句话没错,但是为什么?为什么要设计SPI?还有所谓的拓展者是谁?
从开发能力上说,框架作者能做到的功能,我们普通开发者也一定能做到,只是代码实现优雅,性能略有缺陷。作为一个使用者,肯定会有根据公司产品对某一方面定制化的需求。而dubbo作为一款通用框架,总会有一些什么地方满足不了你定制化的需求,比如说你要根据公司自己的传输协议,传输数据来调用dubbo,这个需求其实很合理。在rpc初级阶段,一些大厂都会自己尝试,就会定义各种自己公司特色的东西,那么dubbo这时肯定不支持。那么这时怎么处理,难道向dubbo开发方pull request?而分支,质量,合并,冲突都会很难管理。
以上是开发的一个痛点,那么dubbo是怎么解决的呢。他在很多地方使用SPI提供了扩展点,当你有定制化需求时,你可以根据SPI的规范,很容易的将自己定制好的某一个功能插在dubbo运行过程中。比如你要定义一个自己的协议。那么你只需要完成以下几步
- 实现org.apache.dubbo.rpc.Protocol。实现定制化需求。
- 在resource/META-INF/dubbo,新建名字为org.apache.dubbo.rpc.Protocol的文件。将自己实现的协议维护在里面。
1
2org.apache.dubbo.rpc.Protocol:
xxx=com.xxx.XxxProtocol - 在dubbo的配置中写上你的协议名字:xxx
1
2<!-- 声明协议,如果没有配置id,将以name为id -->
<dubbo:protocol id="xxx1" name="xxx" />
那么这个时候可以回答那两个问题。为什么要设计SPI?设计SPI的目的就是为方便使用者对已有功能进行扩展,满足使用者定制化的需求。扩展者是谁?扩展者指的就是我们,当我们需要适配自己定制需求时,可以使用SPI扩展点进行扩展。
dubbo扩展点可在官网查看:http://dubbo.apache.org/zh-cn/docs/dev/impls/protocol.html
SPI简单应用
本节使用jdk的SPI,尽量说明SPI的作用。
1 | public interface IWelcome { |
1 | public class LadyWelcome implements IWelcome { |
1 | public class GentlemenWelcome implements IWelcome { |
新建文件META-INF/services/com.ofcoder.xxx.IWelcome
1 | com.ofcoder.xxx.GentlemenWelcome |
测试代码,与结果。
1 | public class Main { |
- 本文链接:https://www.ofcoder.com/2019/08/03/java/%E6%89%8B%E5%86%99dubbo%206-SPI(%E9%A2%84%E7%83%AD%E7%AF%87)/
- 版权声明:Copyright © 并发笔记 - ofcoder.com. Author by far.
分享