一、定义

Dubbo 的 SPI (Service Provider Interface) 机制是对 Java 原生 SPI 机制的增强和扩展,提供了更强大的扩展能力

二、Dubbo SPI 核心实现原理

1、配置文件结构

Dubbo SPI 的配置文件位于:META-INF/dubbo/ 或 META-INF/dubbo/internal/ 或 META-INF/services/

文件名为接口的全限定名,内容为键值对格式:

2、核心类分析

ExtensionLoader,Dubbo SPI 的核心入口类,主要功能:

  • 加载并解析扩展点配置

  • 缓存已加载的扩展点

  • 创建扩展点实例

  • 处理扩展点依赖注入

重要方法:

  • getExtension(String name):获取指定名称的扩展实现

  • getAdaptiveExtension():获取自适应扩展

  • getActivateExtension(URL url, String[] values):获取激活的扩展

扩展点加载流程

1、通过 ExtensionLoader.getExtensionLoader(Class type) 获取扩展点加载器

2、加载器读取配置文件,解析扩展点实现类

3、根据名称实例化具体的扩展点实现

4、注入扩展点的依赖

5、如果存在Wrapper类,进行包装

6、返回最终的扩展点实例

三、Dubbo SPI 高级特性

1、自适应扩展机制 (@Adaptive)

Dubbo 的自适应扩展机制允许在运行时动态选择具体的扩展实现。

实现方式:

Dubbo 会为带有 @Adaptive 注解的方法生成适配代码,根据URL参数动态选择实现

2、自动包装机制 (Wrapper)

Dubbo 支持自动包装扩展点实现,类似AOP的概念。当扩展点实现类的构造函数包含扩展点接口类型参数时,Dubbo会自动将其识别为Wrapper类

示例:

3、自动激活机制 (@Activate)

用于根据条件自动激活一组扩展实现,常用于过滤器、拦截器等场景

可以通过URL参数指定激活哪些扩展:dubbo://service?filter=trace,monitor

四、Dubbo SPI 代码示例

1、定义SPI接口

首先,我们需要定义一个SPI接口。假设我们要创建一个日志记录器接口:

  package com.example.spi;

  public interface Logger {
void log(String message);
}

2、提供接口的实现类

接下来,我们提供该接口的两个实现类:ConsoleLogger.java、FileLogger.java

package com.example.spi.impl;
import com.example.spi.Logger; public class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("ConsoleLogger: " + message);
}
} public class FileLogger implements Logger {
@Override
public void log(String message) {
// 这里只是模拟文件日志记录,实际中应写入文件
System.out.println("FileLogger: " + message);
}
}

3、配置文件

在META-INF/dubbo/com.example.spi.Logger文件中指定实现类的全限定名:

console=com.example.spi.impl.ConsoleLogger
file=com.example.spi.impl.FileLogger

4、使用ExtensionLoader加载实现类

最后,我们使用Dubbo的ExtensionLoader来加载并使用这些实现类:

  package com.example.spi;
import org.apache.dubbo.common.extension.ExtensionLoader; public class SPITest {
public static void main(String[] args) {
// 加载Logger接口的扩展点
ExtensionLoader<logger> loader = ExtensionLoader.getExtensionLoader(Logger.class); // 获取ConsoleLogger实现类实例
Logger consoleLogger = loader.getExtension("console");
consoleLogger.log("This is a console log message."); // 获取FileLogger实现类实例
Logger fileLogger = loader.getExtension("file");
fileLogger.log("This is a file log message.");
}
}

5、运行上述代码,输出结果如下:

ConsoleLogger: This is a console log message.
FileLogger: This is a file log message.

五、Dubbo SPI 源码分析

1、扩展点加载过程

ExtensionLoader 加载扩展点的关键流程:

  • getExtensionLoader():获取或创建指定类型的ExtensionLoader

  • loadExtensionClasses():加载并解析扩展点配置

  • createExtension():创建扩展点实例

    • 通过反射实例化类

    • 执行依赖注入(injectExtension)

    • 应用Wrapper包装

  • 缓存已创建的扩展点实例

2、依赖注入实现

Dubbo 通过 injectExtension() 方法实现依赖注入:

3、自适应扩展代码生成

Dubbo 会为 @Adaptive 方法动态生成适配类,例如:

详细介绍Dubbo的SPI机制的更多相关文章

  1. 面试常问的dubbo的spi机制到底是什么?

    前言 dubbo是一款微服务开发框架,它提供了 RPC通信 与 微服务治理 两大关键能力.作为spring cloud alibaba体系中重要的一部分,随着spring cloud alibaba在 ...

  2. 某大厂面试题:说一说Java、Spring、Dubbo三者SPI机制的原理和区别

    大家好,我是三友~~ 今天来跟大家聊一聊Java.Spring.Dubbo三者SPI机制的原理和区别. 其实我之前写过一篇类似的文章,但是这篇文章主要是剖析dubbo的SPI机制的源码,中间只是简单地 ...

  3. dubbo的spi机制

    SPI SPI是一种扩展机制,在java中SPI机制被广泛应用,比如Spring中的SpringServletContainerInitializer 使得容器启动的时候SpringServletCo ...

  4. Dubbo的SPI机制与JDK机制的不同及原理分析

    从今天开始,将会逐步介绍关于DUbbo的有关知识.首先先简单介绍一下DUbbo的整体概述. 概述 Dubbo是SOA(面向服务架构)服务治理方案的核心框架.用于分布式调用,其重点在于分布式的治理. 简 ...

  5. jdk和dubbo的SPI机制

    前言:开闭原则一直是软件开发领域中所追求的,开闭原则中的"开"是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的,“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代 ...

  6. Dubbo剖析-SPI机制

    文章要点: 1.什么是SPi 2.Dubbo为什么要实现自己的SPi 3.Dubbo的IOC和AOP 4.Dubbo的Adaptive机制 5.Dubbo动态编译机制 6.Dubbo与Spring的融 ...

  7. 详细介绍Java垃圾回收机制

    垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机 ...

  8. dubbo源码分析1——SPI机制的概要介绍

    插件机制是Dubbo用于可插拔地扩展底层的一些实现而定制的一套机制,比如dubbo底层的RPC协议.注册中心的注册方式等等.具体的实现方式是参照了JDK的SPI思想,由于JDK的SPI的机制比较简单, ...

  9. 详解Apache Dubbo的SPI实现机制

    一.SPI SPI全称为Service Provider Interface,对应中文为服务发现机制.SPI类似一种可插拔机制,首先需要定义一个接口或一个约定,然后不同的场景可以对其进行实现,调用方在 ...

  10. Dubbo中SPI扩展机制解析

    dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name, ...

随机推荐

  1. Vim编辑器退出的多种方法

    当文本编辑结束之后,通常需要退出编辑器.退出编辑器又分为4种情况:保存退出.正常退出.不保存退出及强制退出.下面简单说下吧!   1.先介绍一下保存退出.当我们编辑或修改好了文件内容,如图.   我们 ...

  2. 1. Calcite元数据创建

    1. 简介 Calcite 是一款来自 Apache 的开源动态数据管理框架,核心功能是提供 SQL 查询解析.优化及执行等基础能力,以灵活支持多种数据源,广泛应用于各类数据处理系统.以下从其功能特性 ...

  3. flutter中 ListView的使用

    1.ListView的简单介绍 ListView是最常用的可以滚动组件之一, 它可以沿一个方向进行线性排列所有的子组件. 下面是ListView的属性值介绍: scrollDirection:列表的滚 ...

  4. VM1038:1 (in promise) MiniProgramError {"errMsg":"navigateTo:fail webview count limit exceed"} Object解决办法

    在跳转的时候,出现这,有的时候回出现,有的时候不会出现: VM1038:1 (in promise) MiniProgramError {"errMsg":"naviga ...

  5. 【译】轻松评估 AI 应用程序的质量

    原文 | Wendy Breiding 翻译 | 郑子铭 在构建利用 AI 的应用程序时,能够有效地评估 SLM(小型语言模型)或 LLM(大型语言模型)的响应从未如此重要. 评估是指评估 AI 模型 ...

  6. 我来告诉你怎么在macOS上畅玩金铲铲之战

    天选福星,灵蛇献瑞,<金铲铲之战>"天选福星"赛季好运上线!请接收这份来自<金铲铲之战>的新春邀约--"天选福星"正式回归,羁绊焕新升级 ...

  7. flutter-真机调试ios Traceback (most recent call last)

    1 Traceback (most recent call last): 2 File "/tmp/C5FDB25B-C7F4-462E-8AC9-7FF9D1A50F21/fruitstr ...

  8. 用豆包+Kimi,一分钟生成想要的PPT!

    大家好!在快节奏的现代社会,时间就是金钱.对于经常需要制作PPT的朋友们来说,如何快速.高效地完成演示文稿的制作一直是个头疼的问题.今天,我要给大家介绍如何利用AI工具:豆包+kimi,让你在一分钟内 ...

  9. Java8 stream sorted排序时包括null

    开发过程中对象集合根据某个属性排序是常常遇到的情况,但有时排序会遇到对应属性值为null的情况,会报空指针异常. 查找stream.sorted源码看到有Comparator.nullsFirst和C ...

  10. Docker - 部署IT运维管理平台CAT

    原文链接:https://mp.weixin.qq.com/s/Ld9OLnmHP1IAc0Ofo-RzeQ 一.CAT介绍(略) 二.环境规划(略) 三.检查环境(略) 四.部署cat镜像 1.下载 ...