Dubbo 的 ExtensionLoader 小结

本贴最后更新于 2057 天前,其中的信息可能已经水流花落

今天看了下 dubbo 的 SPI 实现,收益匪浅,这里总结一下:

1. 优点:相对于 JDK 原生的 SPI 机制

  1. 按需加载,减少不必要的初始化
  2. 扩展点加载失败,相比 JDK,可以准确报出错误信息
  3. 扩展点可以 IOC 以及 AOP

2. 实现方案

那么 dubbo 是怎么做到以上三点的呢?

1. 按需加载逻辑

以 Transporter 为例,在 getAdaptiveExtension()时才会进行初始化动作,而并非在容器启动时加载所有的扩展类:

imagepng

2. 扩展点加载失败异常报告

在加载失败时会将具体扩展点信息打印出来,即便是循环依赖产生问题,也会准确报出错误信息。

imagepng

3. 扩展点可以 IOC 以及 AOP

首先看下 AOP 的实现,dubbo 在 AOP 上并没有通过字节码修改的方式,而是通过装饰器设计模式来实现的。ExtensionLoader 在加载扩展点时,如果加载到的扩展点有拷贝构造函数,则判定为扩展点 Wrapper 类,而 Wrapper 类并不是真正的实现类,如下图所示:

imagepng

Wrapper 类可以有多个,并且会在所有的扩展点上添加逻辑。我们看下怎么实现的:

imagepng

在创建扩展点时,进行层层装饰,以实现 AOP 的逻辑,设计非常精妙。

我们再来看看 IOC,dubbo 的 IOC,是通过 set 方法进行注入,如下图:

imagepng

如果有多个扩展类可以注入,dubbo 会以如下优先级进行选择注入:

1. 有 @Adaptive 注解的扩展实现类。

在扫描配置文件时,如果发现有 Adaptive 注解的类,则立即加入缓存,以该实现类优先返回。根据代码注意到,同一个扩展点,只能有一个默认实现。

imagepng

扫描配置文件完毕后,如果已经发现找到 Adaptive 注解的类,则返回,代码如下:

imagepng

2. URL 中定义的扩展点。

如果未发现有 @Adaptive 注解的类,dubbo 会动态创建扩展点的实现类,以实现 Adaptive 注解的方法。这里注意到,SPI 接口至少有一个方法需要 @Adaptive 注解,否则报错,如下图所示:

imagepng

createAdaptiveExtensionClassCode 是动态生成 Java 代码的部分,以下截图提取了最关键了部分。可以看看出,如果 URL 中存在定义的扩展点名称,则根据该名称获取对应的扩展实现类。

imagepng

3. @SPI 注解中的 value 定义的实现。

从上图可知,如果 URL 中没有定义,则采用 SPI 的默认扩展名来获取扩展实现类。

3. 参考文献

http://dubbo.apache.org/zh-cn/docs/dev/SPI.html

2.1 jdk-spi的实现原理 - 赵计刚 - 博客园

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1083 引用 • 3461 回帖 • 285 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 608 关注
  • SPI

    Service Provider Interface

    12 引用 • 2 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...