(1) 在协议的实现 jar 包内放置文本文件:META-INF/dubbo/org.apache.dubbo.remoting.api.WireProtocol
properties
复制代码
tri=org.apache.dubbo.rpc.protocol.tri.TripleHttp2Protocol
(2) 实现类内容java
复制代码
@Activate public class TripleHttp2Protocol extends Http2WireProtocol { // ... }
说明下:Http2WireProtocol 实现了 WireProtocol 接口(3) Dubbo 配置模块中,扩展点均有对应配置属性或标签,通过配置指定使用哪个扩展实现 。比如:
xml
复制代码
<dubbo:protocol name="tri" />
从上面的扩展步骤可以看出,用户基本在黑盒下就完成了扩展 。Dubbo 扩展的应用Dubbo 的扩展能力非常灵活,在自身功能的实现上无处不在 。
文章插图
Dubbo 扩展能力使得 Dubbo 项目很方便的切分成一个一个的子模块,实现热插拔特性 。用户完全可以基于自身需求,替换 Dubbo 原生实现,来满足自身业务需求 。
Dubbo SPI 源码分析上面看了 Dubbo SPI 通过
ExtensionLoader
加载扩展 。ExtensionLoader
的 getExtensionLoader
方法获取一个 ExtensionLoader
实例,然后再通过 ExtensionLoader
的 getExtension
方法获取拓展类对象 。这其中,getExtensionLoader
方法用于从缓存中获取与拓展类对应的 ExtensionLoader
,若缓存未命中,则创建一个新的实例 。该方法的逻辑比较简单,本章就不进行分析了 。下面我们从 ExtensionLoader
的 getExtension
方法作为入口,对拓展类对象的获取过程进行详细的分析 。【解析SPI机制:实现灵活插件式架构】
文章插图
上面代码的逻辑比较简单,首先检查缓存,缓存未命中则创建拓展对象 。下面我们来看一下创建拓展对象的过程是怎样的 。
文章插图
createExtension 方法的逻辑稍复杂一下,包含了如下的步骤:
- 通过 getExtensionClasses 获取所有的拓展类
- 通过反射创建拓展对象
- 向拓展对象中注入依赖
- 将拓展对象包裹在相应的 WrApper 对象中
我们在通过名称获取拓展类之前,首先需要根据配置文件解析出拓展项名称到拓展类的映射关系表(Map<名称, 拓展类>),之后再根据拓展项名称从映射关系表中取出相应的拓展类即可 。相关过程的代码分析如下:
文章插图
这里也是先检查缓存,若缓存未命中,则通过 synchronized 加锁 。加锁后再次检查缓存,并判空 。此时如果 classes 仍为 null,则通过 loadExtensionClasses 加载拓展类 。下面分析 loadExtensionClasses 方法的逻辑 。
文章插图
loadExtensionClasses 方法总共做了两件事情,一是对 SPI 注解进行解析,二是调用 loadDirectory 方法加载指定文件夹配置文件 。SPI 注解解析过程比较简单,无需多说 。下面我们来看一下 loadDirectory 做了哪些事情 。
文章插图
loadDirectory 方法先通过 classLoader 获取所有资源链接,然后再通过 loadResource 方法加载资源 。我们继续跟下去,看一下 loadResource 方法的实现 。
文章插图
loadResource 方法用于读取和解析配置文件,并通过反射加载类,最后调用 loadClass 方法进行其他操作 。loadClass 方法用于主要用于操作缓存,该方法的逻辑如下:
文章插图
如上,loadClass 方法操作了不同的缓存,比如 cachedAdaptiveClass、cachedWrapperClasses 和 cachedNames 等等 。除此之外,该方法没有其他什么逻辑了 。
推荐阅读
- 一文解析「小米大模型」
- Java Socket通信与HTTP协议解析
- Oracle数据库初始化参数解析:优化系统配置的终极指南!
- 主动离职,还能收获失业补助金?你不知的“隐藏”福利,一文解析!
- 立竿见影!教师“退出机制”才刚落地,教师招聘就“遇冷”了?
- 王者荣耀:匹配机制恶心人?职业选手的3种逆向思维,带你破局
- React请求机制优化思路
- Java类加载的护城河:深入探究双亲委派机制
- Linux NFSD软件架构与代码解析
- 亚马逊云怎么解析域名?