我是靠谱客的博主 优美酒窝,最近开发中收集的这篇文章主要介绍dubbo的SPI扩展实现原理简解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

最后

以上就是优美酒窝为你收集整理的dubbo的SPI扩展实现原理简解的全部内容,希望文章能够帮你解决dubbo的SPI扩展实现原理简解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部