> 技术文档 > dubbo源码学习4-dubbo的SPI机制详解

dubbo源码学习4-dubbo的SPI机制详解

dubbo SPI 机制使用
通过一下代码可以获取 DubboSpringInitCustomizer 类的所有服务实现

 Set<DubboSpringInitCustomizer> customizers = FrameworkModel.defaultModel()  // 获取DubboSpringInitCustomizer的SPI加载器 .getExtensionLoader(DubboSpringInitCustomizer.class) // 获取所有的实现 .getSupportedExtensionInstances();

然后以DubboSpringInitCustomizer 的全类名 org.apache.dubbo.config.spring.context.DubboSpringInitCustomizer创建一个文件,放置于以下文件夹中的任意一个

META-INF/dubbo/internal/META-INF/dubbo/META-INF/services/

文件内容如下,则创建了一个名为 customizer的自定义实现 com.takemehand.dubbo.MyDubboSpringInitCustomizer,重写 customize 方法即可对dubbo的上下文进行一些自定义的扩展

customizer=com.takemehand.dubbo.MyDubboSpringInitCustomizer

dubbo源码学习4-dubbo的SPI机制详解

org.apache.dubbo.common.extension.ExtensionLoader#loadDirectoryInternal
这个type就是接口的类名
从 LoadingStrategy 中获取文件夹,文件夹 + 类名 就是需要搜索的SPI定义文件

dubbo源码学习4-dubbo的SPI机制详解
通过 ExtensionDirector 创建指定SPI的接口的实现加载器,接口上可以通过 @SPI 来指定 scope
dubbo源码学习4-dubbo的SPI机制详解
直接为该类型创建了一个 ExtensionLoader,然后存入
dubbo源码学习4-dubbo的SPI机制详解
在dubbo中,通过LoadingStrategy来定义了dubbo的SPI路径,对路径的定义有三个SPI,其实现是通过JDK的SPI机制加载的,JDK的SPI机制是将接口定义在 文件夹 META-INF/services/ 下,文件内容填写类名的全路径,一行则为一个类,通过 ServiceLoader.load 加载,如果对JDK的SPI机制还不了解的可以先去学习JDK的SPI机制
dubbo源码学习4-dubbo的SPI机制详解
加载的位置代码位置如下
dubbo源码学习4-dubbo的SPI机制详解
遍历所有定义的文件夹LoadingStrategy
也就是

META-INF/dubbo/internal/META-INF/dubbo/META-INF/services/

dubbo源码学习4-dubbo的SPI机制详解
通过 ClassLoaderResourceLoader 查找文件名为
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
的所有文件列表,从图中可以看到查找到了两个文件

ClassLoaderResourceLoader 就是一个从 resource 文件夹下查找文件的一个资源加载器
dubbo源码学习4-dubbo的SPI机制详解
通过以上文件路径,可以找到以下两个文件,文件内容如下
dubbo源码学习4-dubbo的SPI机制详解
dubbo源码学习4-dubbo的SPI机制详解
org.apache.dubbo.common.extension.ExtensionLoader#loadResource
按行读取文件内容,如果行内容包含 = ,则以 = 号分隔,前面的作为name,= 后面的则是类名全路径,然后通过指定的类加载器,以及 Class.forName 加载该类
dubbo源码学习4-dubbo的SPI机制详解
服务接口上支持添加 dubbo的 @SPI 注解,value标记默认的SPI实现
dubbo源码学习4-dubbo的SPI机制详解
创建 SPI实现 实例时,还支持前后处理,类似于spring创建bean的前后处理
dubbo源码学习4-dubbo的SPI机制详解
以及如果实现了dubbo的 Lifecycle 接口,还支持在实例初始化完成之后的一些扩展
dubbo源码学习4-dubbo的SPI机制详解
获取所有SPI服务实现实例,服务实现可以通过实现 Prioritized 接口,并重写getPriority方法,来实现排序,返回一个有序所有服务实现,有助于我们在扩展的时候,获取 order最大或最小的实现。可以通过在接口上定义的 @SPI的value获取默认的实现。以及在实现类中通过 @Activate 和 @Adaptive注解指定为特定的实现类型
dubbo源码学习4-dubbo的SPI机制详解