您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

浅谈SPI机制之ServiceLoader的原理

时间:2023-12-11 13:46:00  来源:微信公众号  作者:X探险者

今天我们聊聊SPI机制,先从JDK的ServiceLoader 类谈起。

一、 ServiceLoader 介绍

ServiceLoader 类是 JAVA Development Kit (JDK) 的一部分,用于加载服务提供者。这个类是 Java 的服务提供者加载机制(SPI,Service Provider Interface)的核心部分,允许服务提供者被动态地加载到应用程序中。这里的 "服务" 是指一个已知接口或者抽象类的实现,而 "服务提供者" 指的是实现这些接口或类的具体实现。

1.1 功能和用途

  • 动态发现和加载实现: ServiceLoader 可以在运行时动态地查找和加载接口或抽象类的实现,而无需在代码中硬编码它们。
  • 解耦服务接口和实现: 它允许应用程序开发人员将服务接口与其实现分离,增加了代码的模块化和灵活性。
  • 支持插件机制: ServiceLoader 常被用于实现插件架构,允许第三方为应用程序提供扩展或自定义功能。
  • 遵循SPI约定: 服务提供者必须遵守一定的约定,例如在 META-INF/services 目录下提供特定的配置文件。

1.2 工作原理

  • 服务定义: 定义一个服务接口或抽象类。
  • 服务实现: 实现该接口或抽象类。
  • 注册服务提供者: 在类路径的 META-INF/services 目录中创建一个名字与服务接口全名相同的文件,文件内容是实现类的全限定名。
  • 使用 ServiceLoader: 应用程序通过 ServiceLoader 加载服务接口,ServiceLoader 会自动查找并加载实现。

1.3 示例

假设有一个服务接口 MyService 和它的多个实现,可以通过以下方式使用 ServiceLoader 加载它们:

ServiceLoader<MyService> loader = ServiceLoader.load(MyService.class);
for (MyService service : loader) {
    // 使用加载的服务实现
}
  • 1.
  • 2.
  • 3.
  • 4.

1.4 注意事项

  • 类加载器: ServiceLoader 使用当前线程的上下文类加载器来加载服务提供者。
  • 懒加载: ServiceLoader 通常懒加载服务提供者,只有在需要时才加载它们。
  • 错误处理: 如果服务提供者不符合要求(如无法实例化),ServiceLoader 可能会抛出 ServiceConfigurationError。
  • Java模块化: 在 Java 9 及其以上版本中,ServiceLoader 也可以用于模块化系统中。

ServiceLoader 在许多Java应用程序和库中都非常有用,尤其是在那些需要灵活性和解耦合的场景中。

二、 SPI的应用场景

ServiceLoader 作为一种 SPI 机制,在许多主流框架中都有应用,尤其是在需要插件化或模块化的场景中。以下是一些具体的使用场景:

应用框架/技术

SPI 使用场景

Spring 框架

用于加载可插拔组件,如 HttpMessageConverters;在初始化上下文时加载和注册服务和处理器。

Java JDBC API

用于动态加载数据库驱动。当应用尝试连接数据库时,JDBC API 通过 SPI 动态加载可用的数据库驱动。

Java Image I/O API

用于动态发现和加载可用的图像读写器和处理器。

Java 6 及以上版本

SPI 机制被标准化,用于加载各种类型的服务接口实现。

Java Logging API

用于加载日志框架的实现,如可以插拔的日志处理器。

Spring Boot

使用 SPI 机制发现和加载自动配置类 (@Configuration 类),主要通过 spring.factories 文件实现。

OSGi

OSGi 框架使用类似 SPI 的机制来动态管理模块,允许模块在运行时被安装、启动、停止、更新和卸载。

这些示例展示了 SPI 在现代编程框架和库中的广泛应用,突出了其在实现模块化、插拔式架构中的重要性。

  1. Spring 框架:

Spring框架中的一些部分,例如 spring-web, 使用 ServiceLoader 来加载一些可插拔的组件,如 HttpMessageConverters。

在Spring框架的上下文初始化过程中,ServiceLoader 被用来加载和注册各种服务和处理器。

  1. Java JDBC API:

ServiceLoader 在 Java 的 JDBC API 中用于加载数据库驱动。当一个应用程序尝试连接数据库时,JDBC API 通过 ServiceLoader 动态加载可用的数据库驱动。

  1. Java Image I/O API:

在 Java 的 Image I/O API 中,ServiceLoader 用于动态发现和加载可用的图像读写器和图像处理器。

  1. Java 6 中的 java.util.ServiceLoader:

在 Java 6 及以上版本中,ServiceLoader 被标准化,用于加载服务提供者,如各种类型的服务接口实现。

  1. Java Logging API:

在 Java Logging API 中,ServiceLoader 可用于加载日志框架的实现,比如可以插拔的日志处理器。

三、 Spring Boot 对 SPI 的改造和扩展

Spring Boot 对 SPI 机制进行了改造和扩展,使其成为 Spring Boot 自动配置的核心机制之一。这种改造和扩展主要体现在以下几个方面:

  1. 自动配置:

Spring Boot 使用 ServiceLoader 机制来发现和加载自动配置类 (@Configuration 类)。这是通过 spring.factories 文件实现的,该文件位于每个自动配置模块的 META-INF 目录下。

开发者可以通过在 spring.factories 文件中声明自己的自动配置类,来扩展或修改 Spring Boot 的默认行为。

  1. 条件装配:
  • Spring Boot 的自动配置利用了 @Conditional 注解(如 @ConditionalOnClass,@ConditionalOnBean 等),使得仅在满足特定条件时,相关的自动配置类才会被激活和应用。

  • 这种机制结合 ServiceLoader 使得 Spring Boot 能够在运行时根据环境(例如类路径中的类、定义的beans、系统属性等)灵活地加载不同的配置。

  1. 扩展点:

  • Spring Boot 允许开发者通过添加自己的 spring.factories 来扩展或覆盖默认的自动配置,这提供了一个强大的扩展点,使得开发者可以根据自己的需要自定义配置。

通过这些改造和扩展,Spring Boot 极大地简化了 Spring 应用程序的配置,使得开发者可以快速启动和运行基于Spring的项目,同时也保留了高度的可定制性。这种自动配置和条件装配的方法成为了 Spring Boot 的一个显著特点和优势。

四、 思考与拓展

类似于ServiceLoader的这种SPI机制,我更愿意称它为一种框架的插件机制,因为它提供了一种插拔机制,可以让第三方开发人员很容易的对框架进行功能的拓展,这种机制对原框架的功能和新拓展的功能进行了解耦,他们之间通过接口约定,然后基于SPI进行插拔式拓展,非常的灵活。除了 SPI,还有一些其他机制和模式也被用于扩展框架功能,主要包括:

  1. 插件架构(Plugin Architecture):

许多现代软件框架和应用程序采用插件架构,允许第三方开发者通过插件扩展或改变应用程序的功能。例如,IDEs(如 IntelliJ IDEA 或 Eclipse)允许通过插件添加新功能。

插件通常是独立于主应用程序的,通过预定义的API与主应用程序交互。

  1. 事件驱动架构(Event-Driven Architecture, EDA):
  • 在事件驱动架构中,组件之间的通信是基于事件的。这种模式允许应用程序在发生特定事件时触发新的行为,而无需更改发出事件的代码。

  • 这种模式在框架中常用于处理用户界面动作、消息传递等场景。

  1. 反射和动态代理(Reflection and Dynamic Proxy):

  • Java中的反射API允许程序在运行时检查或修改其自身行为。

  • 动态代理是一种常见用法,可以在运行时动态创建一个接口的实现,用于拦截方法调用或改变行为,这在一些框架中用于实现AOP(面向切面编程)。

  1. 依赖注入(Dependency Injection, DI):

  • 依赖注入是一种控制反转(IoC)的形式,常用于框架中管理和配置组件。

  • 通过依赖注入,框架可以动态地为应用程序提供所需的组件,这在Spring等框架中非常普遍。

  1. 组件模型(Component Model):

  • 某些框架提供了一个基于组件的模型,其中应用程序被构建为一系列可以独立开发和部署的组件。

  • OSGi是这种模型的一个例子,它提供了一个动态组件系统,其中组件可以在运行时被安装、启动、停止、更新和卸载。

  1. 模板方法和钩子方法(Template Method and Hook Method):

  • 在模板方法设计模式中,算法的结构由超类定义,而某些步骤则留给子类来实现。

  • 钩子方法提供了在框架的某个特定点插入自定义行为的能力。

这些机制和模式都为软件框架提供了灵活性和扩展性,允许开发者在不改变框架核心代码的前提下增加新的功能或者改变现有功能。这些机制在现代软件开发中非常重要,特别是在构建可扩展、可维护和模块化的应用程序时。



Tags:SPI   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Spider Pool蜘蛛池的正确使用方式
蜘蛛池,英文名为Spider Pool,是一种搜索引擎优化(SEO)技术。它主要通过集中管理大量的搜索引擎蜘蛛(爬虫)来提高网站在搜索引擎中的收录速度和收录率。更通俗易懂地解释,可以想象成...【详细内容】
2024-03-27  Search: SPI  点击:(15)  评论:(0)  加入收藏
说一说SPI是什么,有哪些使用场景?
今天在这里和大家分享一个在技术面试中常被问到的话题&mdash;&mdash;SPI(Service Provider Interface),这是一个令人着迷的技术领域,也是很多Java开发者必须要熟悉的概念。不废...【详细内容】
2023-12-29  Search: SPI  点击:(77)  评论:(0)  加入收藏
浅谈SPI机制之ServiceLoader的原理
今天我们聊聊SPI机制,先从JDK的ServiceLoader 类谈起。一、 ServiceLoader 介绍ServiceLoader 类是 Java Development Kit (JDK) 的一部分,用于加载服务提供者。这个类是 Java...【详细内容】
2023-12-11  Search: SPI  点击:(161)  评论:(0)  加入收藏
深入理解java和dubbo的SPI机制
作者 | 京东云开发者-京东物流 龚航林原文链接:https://my.oschina.net/u/4090830/blog/101160111 SPI 简介1.1 SPI(Service Provider Interface)本质:将接口实现类的全限定名...【详细内容】
2023-10-11  Search: SPI  点击:(243)  评论:(0)  加入收藏
浅析 Java - SPI 机制
作者 | 京东云开发者-京东零售 曹志飞原文链接:https://my.oschina.net/u/4090830/blog/10106105SPI 是什么SPI 全称 Service Provider Interface,是 Java 提供的一套用来被第...【详细内容】
2023-09-01  Search: SPI  点击:(192)  评论:(0)  加入收藏
解析SPI机制:实现灵活插件式架构
什么是SPI机制SPI(Service Provider Interface)是Java中一种服务提供者接口的设计模式,它提供了一种机制,允许组件在不同的实现之间进行插拔,从而实现松耦合的架构。SPI通常用于...【详细内容】
2023-08-27  Search: SPI  点击:(252)  评论:(0)  加入收藏
阿里一面:说一说Java、Spring、Dubbo三者SPI机制的原理和区别
大家好,我是三友~~今天来跟大家聊一聊Java、Spring、Dubbo三者SPI机制的原理和区别。其实我之前写过一篇类似的文章,但是这篇文章主要是剖析dubbo的SPI机制的源码,中间只是简单...【详细内容】
2023-03-14  Search: SPI  点击:(142)  评论:(0)  加入收藏
从实现到原理,聊聊Java中的SPI动态扩展
我们今天暂且不提spring的SPI扩展,先来看看java本身自带的SPI扩展机制是怎么一回事。 八股文背多了,相信大家都听说过一个词,SPI扩展。有的面试官就很喜欢问这个问题,SpringBoo...【详细内容】
2023-02-15  Search: SPI  点击:(221)  评论:(0)  加入收藏
被 Twitter 解雇三个月,他带着竞品 Spill “杀”回来了
整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)距离马斯克收购并接手 Twitter,已经过去了三个月。这也就意味着,第一批被裁的人也已经离开 Twitter 三个月了。这些人中,有的已成功找到下...【详细内容】
2023-02-02  Search: SPI  点击:(159)  评论:(0)  加入收藏
等待的艺术:从Spin Lock到Token Bucket算法
前言CPU (Central Processing Unit)作为整个冯&middot;诺依曼架构的控制与运算中心,终其一生都在执行没有边界的指令,用无差别的计算支撑起智能时代“算力取之不尽用之不竭”的...【详细内容】
2022-10-28  Search: SPI  点击:(241)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(5)  评论:(0)  加入收藏
站内最新
站内热门
站内头条