前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dubbo剖析-增强SPI的实现

Dubbo剖析-增强SPI的实现

作者头像
加多
发布2018-09-06 15:22:05
5330
发布2018-09-06 15:22:05
举报
文章被收录于专栏:Java编程技术Java编程技术

一、前言

在Duboo剖析-整体架构分析中介绍了dubbo中除了Service 和 Config 层为 API外,其他各层均为SPI,为SPI意味着下面各层都是组件化可以被替换的,这也是dubbo比较好的一点。

二、JDK中标准SPI

JDK 中的 SPI(Service Provider Interface)是面向接口编程的,服务规则提供者会在 JRE 的核心 API 里面提供服务访问接口,而具体实现则由其他开发商提供。

例如规范制定者在rt.jar包里面定义了 数据库 的驱动接口 java.sql.Driver。 MySQL 实现的 Jar,如下:

screenshot.png

代码语言:javascript
复制
public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver implements java.sql.Driver

下面我们写个测试代码,看看具体是如何工作的。

代码语言:javascript
复制
    public static void main(String[] args) {
               //(1)
        ServiceLoader<Driver> loader = ServiceLoader.load(Driver.class);
               //(2)
        Iterator<Driver> iterator = loader.iterator();
        while (iterator.hasNext()) {
            Driver driver = (Driver) iterator.next();
            System.out.println("driver:" + driver.getClass() + ",loader:" + driver.getClass().getClassLoader());
        }
        //(3)
        System.out.println("current thread contextloader:" + Thread.currentThread().getContextClassLoader());
               //(4)
        System.out.println("ServiceLoader loader:" + ServiceLoader.class.getClassLoader());
    }

}

然后引入 MySQL 驱动的 Jar 包,执行结果如下。

代码语言:javascript
复制
driver:class com.mysql.jdbc.Driver,loader:sun.misc.Launcher$AppClassLoader@4554617c
current thread contextloader:sun.misc.Launcher$AppClassLoader@4554617c
ServiceLoader loader:null

可知找到了mysql的驱动,如果你在引入Oracle的驱动的jar包后在运行,则会输出找到了mysql和Oracle的驱动,这也说明了,JDK标准的SPI会同时把spi接口的所有的实现类都提前加载好。

关于JDK中SPI的原理和具体使用可以参考 Java 类加载器揭秘 中 一种特殊的类加载器 ContextClassLoader 章节。

三、Dubbo增强的SPI

Dubbo 的扩展点加载是基于JDK 标准的 SPI 扩展点发现机制增强而来的,Dubbo 改进了 JDK 标准的 SPI 的以下问题:

  • JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。
  • 如果扩展点加载失败,就失败了,给用户没有任何通知。比如:JDK 标准的ScriptEngine,如果Ruby ScriptEngine 因为所依赖的 jruby.jar 不存在,导致 Ruby ScriptEngine 类加载失败,这个失败原因被吃掉了,当用户执行 ruby 脚本时,会报空指针异常,而不是报Ruby ScriptEngine不存在。
  • 增加了对扩展点 IoC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点。

下面看看Dubbo增强的SPI实现的时序图:

image.png

  • 其中代码(1)获取当前SPI接口对应的ExtensionLoader
  • 代码(2)获取适配器实例,内部首先获取该spi对应的所有实现类的Class对象,然后创建适配器实例,最后注入该适配器依赖的其他扩展点。
  • 代码(8)根据名称获取具体的spi实现类,内部是创建一个实现类的实例,并使用warp类进行包装后返回。

四、总结

本文简单的介绍了Dubbo中SPI实现原理,更详尽的解析 敬请期待

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.03.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、JDK中标准SPI
  • 三、Dubbo增强的SPI
  • 四、总结
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档