Dubbo程序员我爱编程

Dubbo剖析-增强SPI的实现

2018-03-20  本文已影响61人  阿里加多

一、前言

在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
public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver implements java.sql.Driver

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

    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 包,执行结果如下。

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 的以下问题:

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

image.png

四、总结

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

上一篇下一篇

猜你喜欢

热点阅读