当前位置:首页 > 科技  > 软件

浅谈SPI机制之ServiceLoader的原理

来源: 责编: 时间:2023-12-11 09:27:38 309观看
导读大家好,我是G探险者。今天我们聊聊SPI机制,先从JDK的ServiceLoader 类谈起。一、 ServiceLoader 介绍ServiceLoader 类是 Java Development Kit (JDK) 的一部分,用于加载服务提供者。这个类是 Java 的服务提供者加载机制

大家好,我是G探险者。DxV28资讯网——每日最新资讯28at.com

今天我们聊聊SPI机制,先从JDK的ServiceLoader 类谈起。DxV28资讯网——每日最新资讯28at.com

一、 ServiceLoader 介绍

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

1.1 功能和用途

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

1.2 工作原理

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

1.3 示例

假设有一个服务接口 MyService 和它的多个实现,可以通过以下方式使用 ServiceLoader 加载它们:DxV28资讯网——每日最新资讯28at.com

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

1.4 注意事项

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

ServiceLoader 在许多Java应用程序和库中都非常有用,尤其是在那些需要灵活性和解耦合的场景中。DxV28资讯网——每日最新资讯28at.com

二、 SPI的应用场景

ServiceLoader 作为一种 SPI 机制,在许多主流框架中都有应用,尤其是在需要插件化或模块化的场景中。以下是一些具体的使用场景:DxV28资讯网——每日最新资讯28at.com

应用框架/技术
DxV28资讯网——每日最新资讯28at.com

SPI 使用场景
DxV28资讯网——每日最新资讯28at.com

Spring 框架DxV28资讯网——每日最新资讯28at.com

用于加载可插拔组件,如 HttpMessageConverters;在初始化上下文时加载和注册服务和处理器。DxV28资讯网——每日最新资讯28at.com

Java JDBC APIDxV28资讯网——每日最新资讯28at.com

用于动态加载数据库驱动。当应用尝试连接数据库时,JDBC API 通过 SPI 动态加载可用的数据库驱动。
DxV28资讯网——每日最新资讯28at.com

Java Image I/O APIDxV28资讯网——每日最新资讯28at.com

用于动态发现和加载可用的图像读写器和处理器。
DxV28资讯网——每日最新资讯28at.com

Java 6 及以上版本DxV28资讯网——每日最新资讯28at.com

SPI 机制被标准化,用于加载各种类型的服务接口实现。
DxV28资讯网——每日最新资讯28at.com

Java Logging APIDxV28资讯网——每日最新资讯28at.com

用于加载日志框架的实现,如可以插拔的日志处理器。
DxV28资讯网——每日最新资讯28at.com

Spring BootDxV28资讯网——每日最新资讯28at.com

使用 SPI 机制发现和加载自动配置类 (@Configuration 类),主要通过 spring.factories 文件实现。DxV28资讯网——每日最新资讯28at.com

OSGiDxV28资讯网——每日最新资讯28at.com

OSGi 框架使用类似 SPI 的机制来动态管理模块,允许模块在运行时被安装、启动、停止、更新和卸载。
DxV28资讯网——每日最新资讯28at.com

这些示例展示了 SPI 在现代编程框架和库中的广泛应用,突出了其在实现模块化、插拔式架构中的重要性。DxV28资讯网——每日最新资讯28at.com

  1. Spring 框架:

Spring框架中的一些部分,例如 spring-web, 使用 ServiceLoader 来加载一些可插拔的组件,如 HttpMessageConverters。DxV28资讯网——每日最新资讯28at.com

在Spring框架的上下文初始化过程中,ServiceLoader 被用来加载和注册各种服务和处理器。DxV28资讯网——每日最新资讯28at.com

  1. Java JDBC API:

ServiceLoader 在 Java 的 JDBC API 中用于加载数据库驱动。当一个应用程序尝试连接数据库时,JDBC API 通过 ServiceLoader 动态加载可用的数据库驱动。DxV28资讯网——每日最新资讯28at.com

  1. Java Image I/O API:DxV28资讯网——每日最新资讯28at.com

在 Java 的 Image I/O API 中,ServiceLoader 用于动态发现和加载可用的图像读写器和图像处理器。DxV28资讯网——每日最新资讯28at.com

  1. Java 6 中的 java.util.ServiceLoader:DxV28资讯网——每日最新资讯28at.com

在 Java 6 及以上版本中,ServiceLoader 被标准化,用于加载服务提供者,如各种类型的服务接口实现。DxV28资讯网——每日最新资讯28at.com

  1. Java Logging API:DxV28资讯网——每日最新资讯28at.com

在 Java Logging API 中,ServiceLoader 可用于加载日志框架的实现,比如可以插拔的日志处理器。DxV28资讯网——每日最新资讯28at.com

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

Spring Boot 对 SPI 机制进行了改造和扩展,使其成为 Spring Boot 自动配置的核心机制之一。这种改造和扩展主要体现在以下几个方面:DxV28资讯网——每日最新资讯28at.com

  1. 自动配置:

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

开发者可以通过在 spring.factories 文件中声明自己的自动配置类,来扩展或修改 Spring Boot 的默认行为。DxV28资讯网——每日最新资讯28at.com

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

  • 这种机制结合 ServiceLoader 使得 Spring Boot 能够在运行时根据环境(例如类路径中的类、定义的beans、系统属性等)灵活地加载不同的配置。DxV28资讯网——每日最新资讯28at.com

  1. 扩展点:DxV28资讯网——每日最新资讯28at.com

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

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

四、 思考与拓展

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

  1. 插件架构(Plugin Architecture):

许多现代软件框架和应用程序采用插件架构,允许第三方开发者通过插件扩展或改变应用程序的功能。例如,IDEs(如 IntelliJ IDEA 或 Eclipse)允许通过插件添加新功能。DxV28资讯网——每日最新资讯28at.com

插件通常是独立于主应用程序的,通过预定义的API与主应用程序交互。DxV28资讯网——每日最新资讯28at.com

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

  • 这种模式在框架中常用于处理用户界面动作、消息传递等场景。DxV28资讯网——每日最新资讯28at.com

  1. 反射和动态代理(Reflection and Dynamic Proxy):DxV28资讯网——每日最新资讯28at.com

  • Java中的反射API允许程序在运行时检查或修改其自身行为。DxV28资讯网——每日最新资讯28at.com

  • 动态代理是一种常见用法,可以在运行时动态创建一个接口的实现,用于拦截方法调用或改变行为,这在一些框架中用于实现AOP(面向切面编程)。DxV28资讯网——每日最新资讯28at.com

  1. 依赖注入(Dependency Injection, DI):DxV28资讯网——每日最新资讯28at.com

  • 依赖注入是一种控制反转(IoC)的形式,常用于框架中管理和配置组件。DxV28资讯网——每日最新资讯28at.com

  • 通过依赖注入,框架可以动态地为应用程序提供所需的组件,这在Spring等框架中非常普遍。DxV28资讯网——每日最新资讯28at.com

  1. 组件模型(Component Model):DxV28资讯网——每日最新资讯28at.com

  • 某些框架提供了一个基于组件的模型,其中应用程序被构建为一系列可以独立开发和部署的组件。DxV28资讯网——每日最新资讯28at.com

  • OSGi是这种模型的一个例子,它提供了一个动态组件系统,其中组件可以在运行时被安装、启动、停止、更新和卸载。DxV28资讯网——每日最新资讯28at.com

  1. 模板方法和钩子方法(Template Method and Hook Method):DxV28资讯网——每日最新资讯28at.com

  • 在模板方法设计模式中,算法的结构由超类定义,而某些步骤则留给子类来实现。DxV28资讯网——每日最新资讯28at.com

  • 钩子方法提供了在框架的某个特定点插入自定义行为的能力。DxV28资讯网——每日最新资讯28at.com

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

本文链接:http://www.28at.com/showinfo-26-41703-0.html浅谈SPI机制之ServiceLoader的原理

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 四个令人意外的不可靠可观测性的成本

下一篇: WebSocket:心跳检测与重连机制,你会吗?

标签:
  • 热门焦点
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • Golang 中的 io 包详解:组合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是对Reader和Writer接口的组合,
  • 之家push系统迭代之路

    前言在这个信息爆炸的互联网时代,能够及时准确获取信息是当今社会要解决的关键问题之一。随着之家用户体量和内容规模的不断增大,传统的靠"主动拉"获取信息的方式已不能满足用
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 东方甄选单飞:有些鸟注定是关不住的

    文/彭宽鸿编辑/罗卿东方甄选创始人俞敏洪带队的&ldquo;7天甘肃行&rdquo;直播活动已在近日顺利收官。成立后一年多时间里,东方甄选要脱离抖音自立门户的传闻不绝于耳,&ldquo;7
  • 阿里瓴羊One推出背后,零售企业迎数字化新解

    作者:刘旷近年来随着数字经济的高速发展,各式各样的SaaS应用服务更是层出不穷,但本质上SaaS大多局限于单一业务流层面,对用户核心关切的增长问题等则没有提供更好的解法。在Saa
  • 疑似小米14外观设计图曝光:后置相机模组变化不大

    下半年的大幕已经开启,而谁将成为下半年手机圈的主角就成为了大家关注的焦点,其中被传有望拿下新一代骁龙8 Gen3旗舰芯片的小米14系列更是备受大家瞩
  • OPPO K11样张首曝:千元机影像“卷”得真不错!

    一直以来,OPPO K系列机型都保持着较为均衡的产品体验,历来都是2K价位的明星机型,去年推出的OPPO K10和OPPO K10 Pro两款机型凭借各自的出色配置,堪称有
  • Windows 11发布,微软一改往常对老机型开放的态度

    距离 Windows 11 发布已经过去一周,在过去一周里,很多数码爱好者围绕其对 Android 应用的支持、对老机型的升级问题展开了激烈讨论。与以往不同的是,在这次大
Top