您的位置:首页 > 其它

dubbo的SPI扩展实现原理简解

2017-12-12 19:42 375 查看

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

自定义扩展

实现对应SPI扩展接口

如果是Java项目,则在src下增加META-INF/dubbo目录;如果是Maven项目则在src/main/resources下增加META-INF/dubbo目录

在新增的目录下添加文件,文件名为SPI扩展接口的全限定名

在新增的文件中添加配置名=扩展实现类全限定名,这里的配置名可以理解理解为键值对中的key或者是类似Spring中Bean的ID,而后面的扩展实现类全限定名则是实现,对应的是键值对中的value或者是Bean中class。

在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
b022
/books/dubbo-dev-book/SPI.html

简单来说就是以下三点:

1. 支持懒加载(延迟加载)

2. 异常处理优化

3. 支持AOP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: