Java SPI机制概述

先给出结论:“Java的SPI是一种服务发现机制,用于约定接口和动态发现实现类,体现了分层解耦的思想”。

Java的SPI机制常用于框架扩展或组件替换,最常见的Java SPI应用就是JDBC Driver,JDK提供了java.sql.Driver接口,却将具体的实现交给了相应的数据库驱动,比如:在mysql-connector-java-6.0.6.jar文件中可以看到一个遵循Java SPI机制的文件META-INF/services/java.sql.Driver,并且在该文件中定义了具体的驱动实现类完整限定名称:com.mysql.cj.jdbc.Driver

驱动实现类com.mysql.cj.jdbc.Driver实现了JDK提供的java.sql.Driver接口。

关于Java原生SPI机制的说明详见:Introduction to the Service Provider Interfaces

如何实践Java SPI机制

应用Java SPI机制分为四步:

第一步: 约定接口。

package org.chench.extra.java.spi;
public interface HelloSPI {
void sayHello();
}

第二步: 编写接口实现类。

package org.chench.extra.java.spi;
public class ImageHello implements HelloSPI {
@Override
public void sayHello() {
System.out.println("Image Hello");
}
}

第三步: 在实现类所在的jar包路径META-INF/services下创建一个以“接口完整限定名”命名的描述文件,文件内容为“实现类的完整限定名”(可以是包含多行,每一行是一个实现类的完整限定名)。

如:创建文件META-INF/services/org.chench.extra.java.spi.HelloSPI,内容为:org.chench.extra.java.spi.ImageHello

第四步: 使用Java SPI机制动态加载实现类。

public class SPISample {
public static void main(String[] args) {
// Java SPI机制使用ServiceLoader动态加载实现类
ServiceLoader<HelloSPI> loader = ServiceLoader.load(HelloSPI.class);
Iterator<HelloSPI> iterator = loader.iterator();
while (iterator.hasNext()) {
iterator.next().sayHello();
}
}
}

输出:

Image Hello

如上所示,在Java SPI机制的应用中接口实现类是完全分开的(在不用的jar文件中),所以需要在实现类所在的jar文件中包含一个描述文件。

通常来讲,Java的SPI机制常用于框架中实现功能扩展或替换,即:接口定义和使用ServiceLoader动态加载实现类是在框架代码中,而接口实现类以及描述文件是在扩展代码中,它们分布在不同的jar文件。

实际上,在分布式服务框架Dubbo中也提供了类似于Java原生SPI的扩展机制,详见:自定义扩展

Java原生SPI机制的不足

ServiceLoader类的应用及实现来看,存在一些缺点和不足:

  1. 原生的Java SPI机制只能通过迭代器访问实现类,这样会加载所有在描述文件中的实现类,无法按需加载将造成内存资源浪费。
  2. 多个并发线程使用ServiceLoader示例时不是线程安全的。

为了弥补Java原生SPI机制的不足,Dubbo框架提供了自己的SPI扩展机制,具体使用详见:自定义扩展

【参考】

深入理解 Java 中 SPI 机制

搞懂dubbo的SPI扩展机制

Dubbo 扩展设计理念

Java的SPI机制实践的更多相关文章

  1. java 的SPI机制

    今天看到spring mvc 使用Java Validation Api(JSR-303)进行校验,需要加载一个 其具体实现(比如Hibernate Validator), 本来没有什么问题,但是突然 ...

  2. Java的SPI机制与简单的示例

    一.SPI机制 这里先说下SPI的一个概念,SPI英文为Service Provider Interface单从字面可以理解为Service提供者接口,正如从SPI的名字去理解SPI就是Service ...

  3. Java之SPI机制

    之前开阿里的HSF框架,里面用到了Java的SPI机制,今天闲暇的时候去了解了一下,通过写博客来记录一下 SPI的全名为Service Provider Interface,我对于该机制的理解是为接口 ...

  4. Java的Spi机制心得

    Java spi : 是Java EE 给服务供应商提供的接口,供应商遵循接口契约提供自己的实现.. 简单来讲就是为某个接口寻找服务实现的机制. 在看JDBC源码当看到DriverManage.get ...

  5. 深入理解 Java 中 SPI 机制

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/vpy5DJ-hhn0iOyp747oL5A作者:姜柱 SPI(Service Provider ...

  6. JAVA中SPI机制

    之前研究dubbo的时候就很好奇,里面各种扩展机制,期间也看过很多关于SPI的机制,今日有缘再度看到有文章总结,故记录一下, 首先了解一下 JAVA中SPI简单的用法 可参考这篇文章,https:// ...

  7. Java的SPI机制

    目录 1. 什么是SPI 2. 为什么要使用SPI 3. 关于策略模式和SPI的几点区别 4. 使用介绍或者说约定 4.1 首先介绍几个名词 4.2 约定 5. 具体的demo实现 5.1 创建服务提 ...

  8. Java 的 SPI 机制

    什么是SPI机制? SPI机制( Service Provider Interface)是Java的一种服务发现机制,为了方便应用扩展.那什么是服务发现机制?简单来说,就是你定义了一个接口,但是不提供 ...

  9. Java CAS同步机制 实践应用

    利用CAS实现原子操作类AtomicInteger (这是自定义的AtomicInteger:java有封装好的原子操作AtomicInteger类): class AtomicInteger { p ...

  10. 你应该了解的 Java SPI 机制

    前言 不知大家现在有没有去公司复工,我已经在家办公将近 3 周了,同时也在家呆了一个多月:还好工作并没有受到任何影响,我个人一直觉得远程工作和 IT 行业是非常契合的,这段时间的工作效率甚至比在办公室 ...

随机推荐

  1. [转帖]Alertmanager 部署配置

    https://www.cnblogs.com/winstom/p/11940570.html 目录 前言 源码安装 配置 启动 配置prometheus监控Alertmanager 修改promet ...

  2. [转帖]redis 持久化方式 - aof 和 rdb 区别

    https://wenfh2020.com/2020/04/01/redis-persistence-diff/   aof 和 rdb 是 redis 持久化的两种方式.我们看看它们的特点和具体应用 ...

  3. [1036]kvm虚拟机访问时提示no route to host分析

    环境 宿主机: IP: 10.110.136.43 版本:Kylin Linux Advanced Server release V10 (Sword) KVM vm: IP: 10.110.136. ...

  4. 飞腾2000+上面银河麒麟v10 安装virt-manager创建虚拟机的操作过程

    操作系统安装完之后自带了repos 就可以执行大部分操作, 不需要修改包源 ###Kylin Linux Advanced Server 10 - os repo### [ks10-adv-os] n ...

  5. 使用Grafana 监控 SQLSERVER数据库

    使用Grafana 监控 SQLSERVER数据库 1.获取镜像信息以及启动镜像 docker pull awaragi/prometheus-mssql-exporter docker run -e ...

  6. requests模块安装

    使用python写接口,必不可少的就是requests,所以事先要在python中安装requests     ​一.使用pip install安装(项目的命令行终端使用) 1.配置下载源地址路径(清 ...

  7. java浅拷贝BeanUtils.copyProperties引发的RPC异常 | 京东物流技术团队

    背景 近期参与了一个攻坚项目,前期因为其他流程原因,测试时间已经耽搁了好几天了,本以为已经解决了卡点,后续流程应该顺顺利利的,没想到 人在地铁上,bug从咚咚来~ 没有任何修改的服务接口,抛出异常: ...

  8. elementui中自定义Select选择器样式自定义

    <el-select class="my-el-select" v-model="tenantCont" placeholder="请输入机构标 ...

  9. Jupyter Notebook支持Go

    在执行下列命令之前,请确保你已经安装了Go和Jupyter. gophernotes是针对Jupyter和nteract的Go内核,它可以让你在基于浏览器的笔记本或桌面app上交互式地使用Go.下面介 ...

  10. GitHubDesktop汉化和下载

    GitHubDesktop下载 这玩意官网下载速度特别慢 如果不想等待的可以戳下面链接进行下载 会实时同步更新的 下载地址:GitHubDesktop下载