Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring SPI

Spring SPI

原创
作者头像
疯狂的KK
修改于 2023-11-27 08:11:23
修改于 2023-11-27 08:11:23
1820
举报
文章被收录于专栏:Java项目实战Java项目实战

本文将通过Spring SPI的案例,给大家介绍如何设计一个简单但又强大的SPI扩展机制。

SPI(Service Provider Interface)是一种常用的扩展机制,它通过不改变原有系统的情况下,允许添加新的功能模块。Spring就是利用SPI实现了许多可配置和可替换的设计,比如动态代理,资源加载等功能通过SPI进行扩展。

我们以一个简单的RPC调用接口作为案例,来展示Spring中的SPI设计思路:

代码语言:java
AI代码解释
复制
public interface RpcCall {

  Object call(String url, String method, Object[] args);

}

这个RpcCall接口定义了远程调用的常规操作,我们来看看如何通过SPI来实现不同协议(如HTTP、TCP等)的调用扩展:

代码语言:java
AI代码解释
复制
// RpcCall的默认实现
public class DefaultRpcCall implements RpcCall {

  @Override
  public Object call(String url, String method, Object[] args) {
    // 具体调用实现  
  }

}

定义一个默认实现类,这是SPI不可或缺的一部分。我们通过环境变量配置使用哪个实现:

代码语言:java
AI代码解释
复制
String implementation = 
  System.getenv("rpc.implementation");

RpcCall call;
if(implementation == null){
  call = new DefaultRpcCall();
}else{
  call = loadImplementation(); 
}

//方法调用
call.call("http://localhost:8080","hello",new Object[] {});

loadImplementation方法负责通过反射或其他方式加载配置的实现类:

代码语言:java
AI代码解释
复制
private RpcCall loadImplementation(){

  try{
     Class clazz = Class.forName(implementation);
     return (RpcCall) clazz.getDeclaredConstructor().newInstance();
  }catch(Exception e){
    return new DefaultRpcCall();
  }

}

接下来,我们可以很容易地实现HTTP和TCP两种调用协议:

代码语言:java
AI代码解释
复制
// HTTP 实现
public class HttpRpcCall implements RpcCall{

  @Override
  public Object call(String url, String method, Object[] args){
    // HTTP 实现代码 
  }

}


// TCP 实现  
public class TcpRpcCall implements RpcCall{

  @Override
  public Object call(String url, String method, Object[] args){
   // TCP 实现代码
  }

}

通过设置环境变量"rpc.implementation=com.demo.HttpRpcCall"或"rpc.implementation=com.demo.TcpRpcCall",我们就可以一键切换调用实现而无须修改任何调用代码。

这个架构同样适用于Spring中许多组件的扩展,例如AuthorizationManager、HandlerMethodArgumentResolver等。我们可以通过配置文件或代码方式很方便地切换实现类。

与服务提供者模型(Service Provider Model)相比,SPI能更好地支持热插拔和零配置。开发者也无需修改调用代码就可以扩展新的功能。这给系统架构带来了很好的灵活性。

所以,在设计可扩展组件时,使用SPI提供的接口和默认实现可以帮助我们快速搭建出一个“开放-关闭”和“可配置”的系统框架。这也是Spring之所以如此流行的一个重要原因。

总结来说:

  1. 定义一个标准接口和一个默认实现作为SPI的基础
  2. 通过配置从 SPI 中动态加载完整的实现类
  3. 实现类实例通过接口进行调用操作
  4. 实现无侵入性的拓展能力

当然,SPI还有一些缺点,比如行为不一致、难以升级等。但对于需要动态扩展能力的系统来说,它提供了一种非常简单实用的解决方案。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
dubbo SPI机制源码分析
dubbo是微内核架构,SPI是dubbo的架构根基 什么是微内核?还是开闭原则的应用。把核心流程架构固定,但流程各个节点对重新改进是开放的,也可以说是面下接口编程。具体实现方法就是SPI(servi
技术蓝海
2018/04/26
1.7K0
Dubbo——SPI及自适应扩展原理
Dubbo虽然已交由apache管理,并且社区活跃度也不如SpringCloud,但也是国内应用比较广泛的RPC框架,其背后的设计思想非常值得我们学习借鉴。鉴于Dubbo官方文档对于基础的使用配置已经讲解的非常清楚了,这里就不再赘述。本系列文章将基于Dubbo2.5.3版本的源码做分析。而Dubbo中最核心的一点就是SPI和自适应扩展,Dubbo的高扩展性以及其它功能都是在这个基础上实现的,理解掌握其原理才能看懂后面的一系列功能的实现原理,对我们平时实现高扩展性也非常有帮助。(PS:Dubbo源码不像Zookeeper那样有明确的入口,可以根据官网的源码分析指导找到。)
夜勿语
2020/09/07
6100
【Dubbo源码】SPI机制源码解析
SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,比如 Dubbo 就是通过 SPI 机制加载所有的组件。不过,Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。如果大家想要学习 Dubbo 的源码,SPI 机制务必弄懂。接下来,我们先来了解一下 Java SPI 与 Dubbo SPI 的用法,然后再来分析 Dubbo SPI 的源码。
石臻臻的杂货铺[同名公众号]
2021/07/14
1.5K0
Java必备之从JDK到Dubbo的SPI深度剖析
本示例路径META-INF/services/com.springboot.dubbo.spi.SayHelloService
用户5397975
2019/10/14
9640
dubbo源码之SPI AdaptiveExtension和Wrapper
在之前的推文中我们知道,dubbo有很多SPI的拓展点,而ExtensionLoader又是dubbo SPI拓展点的加载器。这篇文章中我们将以ExtensionLoader为切入点来对dubbo的SPI机制进行分析。dubbo中的SPI拓展点的主要位置在:
山行AI
2019/07/16
1K0
dubbo源码之SPI AdaptiveExtension和Wrapper
dubbo源码学习之SPI(二)
在Dubbo中,SPI是一个非常核心的机制,贯穿在几乎所有的流程中。搞懂这块内容,是接下来了解Dubbo更多源码的关键因素。
周杰伦本人
2022/10/25
3310
dubbo源码学习之SPI(二)
【七夕特殊礼物】Dubbo学习之SPI实战与debug源码
上篇文章《dubbo学习之源码创建属于自己的dubbo-demo》溪源带着大家简单搭建了自己的demo,基础环境已经搭建完成,从这篇文章开始,溪源便开始学习并总结Dubbo的相关机制,此篇文章的核心是实践SPI机制和SPI源码跟踪。时间宝贵,下面步入正题: 对于SPI机制,溪源不再做介绍了,大家有兴趣的可以自行谷歌,同时分享溪源之前总结的:java实践SPI机制及浅析源码。
沁溪源
2020/09/03
3320
剖析 SPI 在 Spring 中的应用
SPI(Service Provider Interface),是Java内置的一种服务提供发现机制,可以用来提高框架的扩展性,主要用于框架的开发中,比如Dubbo,不同框架中实现略有差异,但核心机制相同,而Java的SPI机制可以为接口寻找服务实现。SPI机制将服务的具体实现转移到了程序外,为框架的扩展和解耦提供了极大的便利。
2020labs小助手
2022/06/21
1.2K0
Dubbo SPI实现原理
Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求,在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展. 本篇文章通过示例说明,先 download 代码,然后在 demo-dubbo--》dubbo-demo-api--》dubbo-demo-api-provider 下新建类:
LiosWong
2019/11/06
1.3K0
Dubbo SPI实现原理
真的够可以的,基于Netty实现了PRC框架
RPC全称Remote Procedure Call,即远程过程调用,对于调用者无感知这是一个远程调用功能。目前流行的开源RPC 框架有阿里的Dubbo、Google 的 gRPC、Twitter 的Finagle 等。本次RPC框架的设计主要参考的是阿里的Dubbo,这里Netty 基本上是作为架构的技术底层而存在的,主要完成高性能的网络通信,从而实现高效的远程调用。
Java程序猿阿谷
2021/04/09
8150
真的够可以的,基于Netty实现了PRC框架
【DUBBO】 扩展机制ServiceLoaderExtensionLoader
可扩展机制也就是SPI(Service Provider Interface)了,SPI是一种服务提供发现机制。一个服务通常指的是已知的接口,服务提供方就是这个接口的实现类,然后按照SPI标准存放到资源路径META-INF/services目录下,文件的命名为该服务接口的全限定名。
spilledyear
2018/12/21
9760
Spring Boot 插件化开发模式,真香!
实现服务模块之间解耦的方式有很多,但是插件来说,其解耦的程度似乎更高,而且更灵活,可定制化、个性化更好。
码农编程进阶笔记
2024/12/20
2420
Spring Boot 插件化开发模式,真香!
如何在项目中引入SPI
SPI 全称是 Service Provider Interface,是一种将服务接口与服务实现分离以达到解耦、可以提升程序可扩展性的机制。引入服务提供者就是引入了 SPI 接口的实现者,通过本地的注册发现获取到具体的实现类,可以在运行时,动态为接口替换实现类,实现服务的热插拔。
PPPHUANG
2022/04/22
5210
如何在项目中引入SPI
JDK、Dubbo、Spring 三种 SPI 机制,谁更好?
公众号运营至今,离不开小伙伴们的支持。为了给小伙伴们提供一个互相交流的平台,特地开通了官方交流群。关注公众号「Java后端技术全栈」回复「进群」即可。
田维常
2021/05/11
7090
[适合初中级Java程序员修炼手册从0搭建整个Web项目](七)
一个Web后端框架的轮子从处理Http请求【基于Netty的请求级Web服务器】 到mvc【接口封装转发)】,再到ioc【依赖注入】,aop【切面】,再到 rpc【远程过程调用】最后到orm【数据库操作】全部自己撸一个(简易)的轮子。
用户9927510
2022/07/29
2310
[适合初中级Java程序员修炼手册从0搭建整个Web项目](七)
JDK/Dubbo/Spring 三种 SPI 机制,谁更好?
这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。
终码一生
2022/04/14
2950
JDK/Dubbo/Spring 三种 SPI 机制,谁更好?
举个栗子,现在我们设计了一款全新的日志框架:super-logger 。默认以XML文件作为我们这款日志的配置文件,并设计了一个配置文件解析的接口:
芋道源码
2021/05/10
5000
JDK/Dubbo/Spring 三种 SPI 机制,谁更好?
Dubbo的SPI机制详解
Dubbo SPI 逻辑封装在 ExtensionLoader 类,通过 ExtensionLoader,可加载指定实现类。Dubbo SPI 所需配置文件需放置在 META-INF/dubbo 路径:
JavaEdge
2022/11/30
3820
Dubbo的SPI机制详解
[转] 理解 Dubbo SPI 扩展机制
    最近接触了 gRPC 体会到虽然众多 RPC 框架各有各的特点但是他们提供的特性和功能有很多的相似之处 , 这就说明他们面对同样的分布式系统带来的问题。从 2016 年左右开始接触到 dubbo ,基本停留在使用的层面,对 dubbo 的设计以及着重要解决的问题都没有系统的研究过,通过对 dubbo 和其他类似 RPC 产品的系统学习 ,学习分布式系统中面临的共同问题以及解决之道。 
JMCui
2019/06/03
4730
dubbo 源码 v2.7 分析:核心机制(二)
上一篇重点讲了dubbo中的几种设计模式,和对应的源码。本篇会继续介绍Bean加载、Extension、代理几种机制在dubbo中的应用。
程序员架构进阶
2021/03/02
3030
dubbo 源码 v2.7 分析:核心机制(二)
相关推荐
dubbo SPI机制源码分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档