Dubbo的SPI是个什么鬼
原文:https://mp.weixin.qq.com/s/bQc_tASkfsojlcd897kLtA
# spi 是啥?
spi,简单来说,就是 service provider interface,说白了是什么意思呢,比如你有个接口,现在这个接口有 3 个实现类,那么在系统运行的时候对这个接口到底选择哪个实现类呢?这就需要 spi 了,需要根据指定的配置或者是默认的配置,去找到对应的实现类加载进来,然后用这个实现类的实例对象。
举个栗子。
你有一个接口 A。A1/A2/A3 分别是接口A的不同实现。你通过配置 接口 A = 实现 A2,那么在系统实际运行的时候,会加载你的配置,用实现 A2 实例化一个对象来提供服务。
spi 机制一般用在哪儿?插件扩展的场景,比如说你开发了一个给别人使用的开源框架,如果你想让别人自己写个插件,插到你的开源框架里面,从而扩展某个功能,这个时候 spi 思想就用上了。
# Java spi 思想的体现
spi 经典的思想体现,大家平时都在用,比如说 jdbc。
Java 定义了一套 jdbc 的接口,但是 Java 并没有提供 jdbc 的实现类。
但是实际上项目跑的时候,要使用 jdbc 接口的哪些实现类呢?一般来说,我们要根据自己使用的数据库,比如 mysql,你就将 mysql-jdbc-connector.jar 引入进来;oracle,你就将 oracle-jdbc-connector.jar 引入进来。
在系统跑的时候,碰到你使用 jdbc 的接口,他会在底层使用你引入的那个 jar 中提供的实现类。
# dubbo 的 spi 思想
dubbo 也用了 spi 思想,不过没有用 jdk 的 spi 机制,是自己实现的一套 spi 机制。
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
Protocol 接口,在系统运行的时候,,dubbo 会判断一下应该选用这个 Protocol 接口的哪个实现类来实例化对象来使用。
它会去找一个你配置的 Protocol,将你配置的 Protocol 实现类,加载到 jvm 中来,然后实例化对象,就用你的那个 Protocol 实现类就可以了。
上面那行代码就是 dubbo 里大量使用的,就是对很多组件,都是保留一个接口和多个实现,然后在系统运行的时候动态根据配置去找到对应的实现类。如果你没配置,那就走默认的实现好了,没问题。
@SPI("dubbo")
public interface Protocol { int getDefaultPort(); @Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException; @Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException; void destroy(); }
在 dubbo 自己的 jar 里,在/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件中:
dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
所以说,这就看到了 dubbo 的 spi 机制默认是怎么玩儿的了,其实就是 Protocol 接口,@SPI("dubbo") 说的是,通过 SPI 机制来提供实现类,实现类是通过 dubbo 作为默认 key 去配置文件里找到的,配置文件名称与接口全限定名一样的,通过 dubbo 作为 key 可以找到默认的实现类就是 com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol。
如果想要动态替换掉默认的实现类,需要使用 @Adaptive 接口,Protocol 接口中,有两个方法加了 @Adaptive 注解,就是说那俩接口会被代理实现。
啥意思呢?
比如这个 Protocol 接口搞了俩 @Adaptive 注解标注了方法,在运行的时候会针对 Protocol 生成代理类,这个代理类的那俩方法里面会有代理代码,代理代码会在运行的时候动态根据 url 中的 protocol 来获取那个 key,默认是 dubbo,你也可以自己指定,你如果指定了别的 key,那么就会获取别的实现类的实例了。
# 如何自己扩展 dubbo 中的组件
下面来说说怎么来自己扩展 dubbo 中的组件。
自己写个工程,要是那种可以打成 jar 包的,里面的 src/main/resources 目录下,搞一个 META-INF/services,里面放个文件叫:com.alibaba.dubbo.rpc.Protocol,文件里搞一个my=com.bingo.MyProtocol。自己把 jar 弄到 nexus 私服里去。
然后自己搞一个 dubbo provider 工程,在这个工程里面依赖你自己搞的那个 jar,然后在 spring 配置文件里给个配置:
<dubbo:protocol name=”my” port=”20000” />
provider 启动的时候,就会加载到我们 jar 包里的my=com.bingo.MyProtocol 这行配置里,接着会根据你的配置使用你定义好的 MyProtocol 了,这个就是简单说明一下,你通过上述方式,可以替换掉大量的 dubbo 内部的组件,就是扔个你自己的 jar 包,然后配置一下即可。
dubbo 里面提供了大量的类似上面的扩展点,就是说,你如果要扩展一个东西,只要自己写个 jar,让你的 consumer 或者是 provider 工程,依赖你的那个 jar,在你的 jar 里指定目录下配置好接口名称对应的文件,里面通过 key=实现类。
然后对于对应的组件,类似 <dubbo:protocol> 用你的那个 key 对应的实现类来实现某个接口,你可以自己去扩展 dubbo 的各种功能,提供你自己的实现。
Dubbo的SPI是个什么鬼的更多相关文章
- Dubbo中SPI扩展机制解析
dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name, ...
- Dubbo剖析-SPI机制
文章要点: 1.什么是SPi 2.Dubbo为什么要实现自己的SPi 3.Dubbo的IOC和AOP 4.Dubbo的Adaptive机制 5.Dubbo动态编译机制 6.Dubbo与Spring的融 ...
- dubbo的spi机制
SPI SPI是一种扩展机制,在java中SPI机制被广泛应用,比如Spring中的SpringServletContainerInitializer 使得容器启动的时候SpringServletCo ...
- Dubbo学习笔记6:Dubbo增强SPI与SPI中扩展点自动包装的实现原理
在Dubbo整体架构分析中介绍了Dubbo中除了Service和Config层为API外,其他各层均为SPI,为SPI意味着下面各层都是组件化可以被替换的,也就是扩展性比较强,这也是Dubbo比较好的 ...
- dubbo 的 spi 思想是什么?
面试题 dubbo 的 spi 思想是什么? 面试官心理分析 继续深入问呗,前面一些基础性的东西问完了,确定你应该都 ok,了解 dubbo 的一些基本东西,那么问个稍微难一点点的问题,就是 spi, ...
- 4.dubbo 的 spi 思想是什么?
作者:中华石杉 面试题 dubbo 的 spi 思想是什么? 面试官心理分析 继续深入问呗,前面一些基础性的东西问完了,确定你应该都 ok,了解 dubbo 的一些基本东西,那么问个稍微难一点点的问题 ...
- 分布式的几件小事(五)dubbo的spi思想是什么
1.什么是SPI机制 SPI 全称为 Service Provider Interface,是一种服务发现机制. SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实 ...
- jdk和dubbo的SPI机制
前言:开闭原则一直是软件开发领域中所追求的,开闭原则中的"开"是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的,“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代 ...
- Dubbo的SPI机制与JDK机制的不同及原理分析
从今天开始,将会逐步介绍关于DUbbo的有关知识.首先先简单介绍一下DUbbo的整体概述. 概述 Dubbo是SOA(面向服务架构)服务治理方案的核心框架.用于分布式调用,其重点在于分布式的治理. 简 ...
随机推荐
- Hadoop HA 搭建
Hadoop HA 什么是 HA HA是High Available缩写,是双机集群系统简称,指高可用性集群,是保证业务连续性的有效解决方案,一般有两个或两个以上的节点,且分为活动节点及备用节点.通常 ...
- js入门之字符串常用的方法
一. 概念理解基本包装类型 1. 基本包装类型 三种基本包装类型 String var s = new String('123dddd'); Number Boolean 简单类型没有方法和属性 之所 ...
- Eclipse 交叉编译环境
创建空工程 添加交叉编译环境 添加工程文件 如需修改交叉编译环境 Cross GCC:使用交叉编译命令编译,需要自己指定 MinGW GCC:使用make命令编译,需要有Makefile Make T ...
- ABAP Netweaver体内的那些寄生式编程语言
今天这篇文章的主题是:寄生. Jerry最近看到朋友圈里一位朋友分享的一张寄居蟹的照片,对于Jerry这种在内地长大的又很宅的人来说,没有机会看到寄居蟹,所以觉得很新鲜: 寄居蟹主要以螺壳为寄体,寄居 ...
- MySQL索引机制详解(B+树)
一.索引是什么? 索引是为了加速对表中数据行的检索而创建的一种分散存储的数据结构. 二.为什么要使用索引? 索引能极大的减少存储引擎需要扫描的数据量. 索引可以把随机IO变成顺序IO. 索引可以帮助我 ...
- 七年总结常用 Git 命令清单
我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下 ...
- 异常-Maxwell无法全量同步触发
因为之前插入错误的表导致同步失败的问题 重新启动Maxwell,重新插入初始化表 重新触发
- cuda实现向量相加
cuda实现向量相加 博客最后附上整体代码 如果有说的不对的地方还请前辈指出, 因为cuda真的接触没几天 一些总结(建议看) cuda 并不纯GPU在运行程序, 而是 cpu 与 gpu 一起在运行 ...
- 安装Windows8/Windows10时,在安装界面提示无法在此驱动器上安装Windows
该方法会清除整个硬盘上的数据,这是对整个硬盘的操作,如果你有多个硬盘,请一定要选好哪块硬盘,其他的硬盘数据不会被清除. 1.在当前的安装界面按Shift + F10,打开cmd窗口 2.输入diskp ...
- Nginx基本参数调优
Nginx基本参数 #运行用户 user nobody; #worker进程的个数:通常应该为物理CPU核数减1: #可以为”auto”,实现自动设定(worker_processes auto) ...