搞定 Dubbo 系列(二):SPI 机制探讨
一、啥是 Dubbo SPI
SPI(Service Provider Interface),是一种服务发现机制。Dubbo SPI 源于 JDK SPI,并做了增强处理。简单理解:定义一个接口,并不用关心具体实现。其他人按照这个接口去实现内容。当需要接入别人的实现时,需要一种机制来保证他的内容被正确的加载运行,这就是 SPI。同时,可以在运行时,动态为接口替换实现类,增强了扩展性。
二、 Dubbo SPI vs JDK SPI
Dubbo SPI 在官方文档中叫做 扩展点,由 JDK 标准的 SPI 扩展点发现机制加强而来。Dubbo SPI 主要增强了以下三点,
- jdk SPI仅通过接口类名获取所有实现,但是Duboo SPI可以根据接口类名和key值获取具体一个实现,不会一次性实例化所有实现,而只在需要时实例化。
- 扩展点加载失败的原因有更清楚的展示。
- 增加了 IoC 和 AOP 的支持。
三、Dubbo中的配置
dubbo的约定:在扩展类的 jar 包内 ,放置扩展点配置文件 META-INF/dubbo/接口全限定名
,内容为:配置名=扩展实现类全限定名
,多个实现类用换行符分隔。以扩展 Dubbo 的协议为例,
1、在协议的实现 jar 包内放置文本文件:META-INF/dubbo/org.apache.dubbo.rpc.Protocol
,内容为:
xxx=com.alibaba.xxx.XxxProtocol
2、实现类:
package com.alibaba.xxx;
import org.apache.dubbo.rpc.Protocol;
public class XxxProtocol implements Protocol {
// ...
}
3、Dubbo 配置模块中,扩展点均有对应配置属性或标签,通过配置指定使用哪个扩展实现。比如:
<dubbo:protocol name="xxx" />
四、SPI特性(扩展点特性)
1、扩展点自动包装
自动包装扩展点的 Wrapper 类。ExtensionLoader
在加载扩展点时,如果加载到的扩展点有拷贝构造函数,则判定为扩展点 Wrapper 类。
2、扩展点自动装配
加载扩展点时,自动注入依赖的扩展点。加载扩展点时,扩展点实现类的成员如果为其它扩展点类型,ExtensionLoader
在会自动注入依赖的扩展点。ExtensionLoader
通过扫描扩展点实现类的所有 setter 方法来判定其成员。即 ExtensionLoader
会执行扩展点的拼装操作。
3、扩展点自适应
ExtensionLoader
注入的依赖扩展点是一个 Adaptive
实例,直到扩展点方法执行时才决定调用是哪一个扩展点实现。
4、扩展点自动激活
对于集合类扩展点,比如:Filter
, InvokerListener
, ExportListener
, TelnetHandler
, StatusChecker
等,可以同时加载多个实现,此时,可以用自动激活来简化配置。
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Filter;
@Activate // 无条件自动激活
public class XxxFilter implements Filter {
// ...
}
@Activate("xxx") // 当配置了xxx参数,并且参数为有效值时激活,比如配了cache="lru",自动激活CacheFilter。
public class XxxFilter implements Filter {
// ...
}
@Activate(group = "provider", value = "xxx") // 只对提供方激活,group可选"provider"或"consumer"
public class XxxFilter implements Filter {
// ...
}
还没有评论,来说两句吧...