Dubbo源码解读——Dubbo扩展点加载机制

编程

Dubbo源码解读 —— Dubbo扩展点加载机制

Dubbo源码解读 —— Dubbo扩展点加载机制  1、SPI介绍  2、Java SPI 实现  3、Dubbo Spi 实现  4、Dubbo 中扩展核心类源码解析  5、记录的知识点

1、SPI介绍

  • SPI : Service Provider Interface,种服务发现机制。

  • 本质是将接口实现类的全路径名配置在文件中,由服务加载器读取配置文件,加载实现类。

  • 可以在运行时,动态为接口替换实现类。

  • 可以很容易的通过 SPI 机制为我们的程序提供拓展功能。

  • SPI 机制在第三方框架中也有所应用。

2、Java SPI 实现

  1. 定义一个接口及对应的方法

    public interface IJavaSpiService {

      Object say(String param);

    }

  2. 实现接口定义的方法

    public class JavaSpiServiceImpl implements IJavaSpiService {

      @Override

      public Object say(String param) {

          System.out.println("java spi impl "+param);

          return "java spi impl";

      }

    }

    public class Java1SpiServiceImpl implements IJavaSpiService {

      @Override

      public Object say(String param) {

          System.out.println("java spi impl "+param);

          return "java spi impl";

      }

    }

  3. 数据配置文件

  4. ServiceLoader加载具体的实现类

      @Test

      public void javaSpi() {

          ServiceLoader<IJavaSpiService> spiServices = ServiceLoader.load(IJavaSpiService.class);

          spiServices.forEach(vo->{

              vo.say(vo.getClass().getCanonicalName());

          });

      }

  5. Java Spi

    • JDK标准的SPI会一次性实例化扩展点所有的实现,如果有扩展实现,则初始化很耗时,若没有,也加载,浪费资源。

    • 扩展加载失败,则获取不到扩展的名称

3、Dubbo Spi 实现

  1. Dubbo SPI 是通过键值对的方式进行配置,这样可以按需加载实现类。

  2. 可以按需加载制定的实现类。

  3. Dubbo SPI 所需的配置文件需放置在 META-INF/dubbo 路径下。

  4. Dubbo 实现了AOP 和IOC机制

  5. 实现源码:

    @SPI

    public interface IDubboSpiService {

      Object say();

    }

    public class DubboSpiServiceImpl implements IDubboSpiService {

      @Override

      public Object say() {

          System.out.println("dubbo spi impl ");

          return this.getClass().getCanonicalName();

      }

    }

      @Test

      public void dubboSpi() throws Exception {

          ExtensionLoader<IDubboSpiService> extensionLoader = ExtensionLoader.getExtensionLoader(IDubboSpiService.class);

          IDubboSpiService dubboSpiServiceImpl = extensionLoader.getExtension("dubboSpiServiceImpl");

          System.out.println(dubboSpiServiceImpl.say());

          IDubboSpiService iDubboSpiService = extensionLoader.getExtension("dubbo1SpiServiceImpl");

          System.out.println(iDubboSpiService.say());

      }

4、Dubbo 中扩展核心类源码解析

  • Dubbo 扩展核心类在 dubbo-common模块下,ExtensionLoader,主要方法:getExtension(获得普通扩展类)、getActivateExtension(获得自动激活扩展类)、getAdaptiveExtension(获取自适应扩展类)

  • 核心方法getExtension解读:

    • 从缓存中先获取目标对象,然后双重锁判断创建扩展实例

    • 创建扩展实例:createExtension

    • 加载扩展类,解析SPI注解

  • Dubbo IOC

    Dubbo IOC 是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中.方法:injectExtension

     

5、记录的知识点

  • 核心类(ExtensionLoader)如何创建?

    通过工厂类:ExtensionFactory

/**

* ExtensionFactory

*/

@SPI

public interface ExtensionFactory {

  /**

    * Get extension.

    *

    * @param type object type.

    * @param name object name.

    * @return object instance.

    */

  <T> T getExtension(Class<T> type, String name);

}

  • Dubbo 与 Spring 打通的桥梁是?

具体实现类有:SpringExtensionFactory中有Spring上下文环境ApplicationContext

  • SPI 使用了类缓存,实例缓存,缓存使用ConcurrentMap实现

读源码不易,其读其珍惜~~

以上是 Dubbo源码解读——Dubbo扩展点加载机制 的全部内容, 来源链接: utcz.com/z/514888.html

回到顶部