dubbo的SPI扩展实现原理简解

1 篇文章 0 订阅

Java的SPI简介

Java中的SPI是通过接口+配置文件实现动态加载实现,使用方法及原理如下:

  1. 创建SPI需要的接口,其实就是常见的接口文件
  2. 实现创建的接口
  3. 如果是Java项目,则在src下增加META-INF/services目录;如果是Maven项目则在src/main/resources下增加META-INF/services目录
  4. 在META-INF/services创建一个以接口的**全限定名(包含完整包名的类名)**为文件名的文件,在这个文件中添加接口实现类的全限定名。
  5. 使用java.util.ServiceLoader类的load方法加载以接口的全限定名为文件名的文件声明的服务,使用迭代器(java.util.ServiceLoader的iterator方法)遍历。

PS: java.util.ServiceLoader只会在META-INF/services目录下加载配置是因为这个类中已经声明了加载的前缀为META-INF/services

dubbo中的SPI

ExtensionLoader

在dubbo中也参考Java的SPI实现了自己的SPI,其中核心类就是com.alibaba.dubbo.common.extension.ExtensionLoader。该类提供了SPI的配置解析和动态加载实现类

ExtensionLoader规定了dubbo本身的SPI扩展点配置文件放在dubbo.jar的META-INF/dubbo/internal目录下,文件名要求为全限定接口名,文件内容为配置名=扩展实现类全限定名,多个实现类用换行符分隔。

同时ExtensionLoader也规定了开发者自行的扩展会去META-INF/dubbo目录下检索开发者的实现。

ExtensionFactory

com.alibaba.dubbo.common.extension.ExtensionFactory是获取ExtensionLoader实例的工厂接口,内部只有一个获取扩展点的抽象方法。

dubbo内部只有3个ExtensionFactory的实现类,可以在duubo.jar的META-INF/dubbo/internal/com.alibaba.dubbo.common.extension.ExtensionFactory文件中找到,内容如下:

adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory

其中AdaptiveExtensionFactory是适配器扩展点工厂,SpiExtensionFactory是SPI扩展点工厂,SpringExtensionFactory是Spring扩展点工厂。

AdaptiveExtensionFactory管理其他的扩展点工厂,包括SpiExtensionFactorySpringExtensionFactory

自定义扩展
  1. 实现对应SPI扩展接口
  2. 如果是Java项目,则在src下增加META-INF/dubbo目录;如果是Maven项目则在src/main/resources下增加META-INF/dubbo目录
  3. 在新增的目录下添加文件,文件名为SPI扩展接口的全限定名
  4. 在新增的文件中添加配置名=扩展实现类全限定名,这里的配置名可以理解理解为键值对中的key或者是类似Spring中Bean的ID,而后面的扩展实现类全限定名则是实现,对应的是键值对中的value或者是Bean中class。
  5. 在dubbo的配置文件中对应的配置中使用你的配置名。

JAVA的SPI和dubbo的SPI的区别:

以下是官网的内容:

Dubbo 的扩展点加载从 JDK 标准的 SPI (Service Provider Interface) 扩展点发现机制加强而来。
Dubbo 改进了 JDK 标准的 SPI 的以下问题:

  1. JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。
  2. 如果扩展点加载失败,连扩展点的名称都拿不到了。比如:JDK 标准的 ScriptEngine,通过 getName() 获取脚本类型的名称,但如果 RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby 脚本时,会报不支持 ruby,而不是真正失败的原因。
  3. 增加了对扩展点 IoC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点。

原文地址:http://dubbo.io/books/dubbo-dev-book/SPI.html

简单来说就是以下三点:

  1. 支持懒加载(延迟加载)
  2. 异常处理优化
  3. 支持AOP
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值