Java的SPI机制实践
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类的应用及实现来看,存在一些缺点和不足:
- 原生的Java SPI机制只能通过迭代器访问实现类,这样会加载所有在描述文件中的实现类,无法按需加载将造成内存资源浪费。
- 多个并发线程使用
ServiceLoader示例时不是线程安全的。
为了弥补Java原生SPI机制的不足,Dubbo框架提供了自己的SPI扩展机制,具体使用详见:自定义扩展。
【参考】
深入理解 Java 中 SPI 机制
搞懂dubbo的SPI扩展机制
Dubbo 扩展设计理念
Java的SPI机制实践的更多相关文章
- java 的SPI机制
今天看到spring mvc 使用Java Validation Api(JSR-303)进行校验,需要加载一个 其具体实现(比如Hibernate Validator), 本来没有什么问题,但是突然 ...
- Java的SPI机制与简单的示例
一.SPI机制 这里先说下SPI的一个概念,SPI英文为Service Provider Interface单从字面可以理解为Service提供者接口,正如从SPI的名字去理解SPI就是Service ...
- Java之SPI机制
之前开阿里的HSF框架,里面用到了Java的SPI机制,今天闲暇的时候去了解了一下,通过写博客来记录一下 SPI的全名为Service Provider Interface,我对于该机制的理解是为接口 ...
- Java的Spi机制心得
Java spi : 是Java EE 给服务供应商提供的接口,供应商遵循接口契约提供自己的实现.. 简单来讲就是为某个接口寻找服务实现的机制. 在看JDBC源码当看到DriverManage.get ...
- 深入理解 Java 中 SPI 机制
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/vpy5DJ-hhn0iOyp747oL5A作者:姜柱 SPI(Service Provider ...
- JAVA中SPI机制
之前研究dubbo的时候就很好奇,里面各种扩展机制,期间也看过很多关于SPI的机制,今日有缘再度看到有文章总结,故记录一下, 首先了解一下 JAVA中SPI简单的用法 可参考这篇文章,https:// ...
- Java的SPI机制
目录 1. 什么是SPI 2. 为什么要使用SPI 3. 关于策略模式和SPI的几点区别 4. 使用介绍或者说约定 4.1 首先介绍几个名词 4.2 约定 5. 具体的demo实现 5.1 创建服务提 ...
- Java 的 SPI 机制
什么是SPI机制? SPI机制( Service Provider Interface)是Java的一种服务发现机制,为了方便应用扩展.那什么是服务发现机制?简单来说,就是你定义了一个接口,但是不提供 ...
- Java CAS同步机制 实践应用
利用CAS实现原子操作类AtomicInteger (这是自定义的AtomicInteger:java有封装好的原子操作AtomicInteger类): class AtomicInteger { p ...
- 你应该了解的 Java SPI 机制
前言 不知大家现在有没有去公司复工,我已经在家办公将近 3 周了,同时也在家呆了一个多月:还好工作并没有受到任何影响,我个人一直觉得远程工作和 IT 行业是非常契合的,这段时间的工作效率甚至比在办公室 ...
随机推荐
- [转帖]【Redis】Redis中使用Lua脚本
Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua具体语法参考:https://www.runoob. ...
- 【转帖】【笔记】python连接神通数据库
https://www.cnblogs.com/wyongbo/p/17054924.html python连接国产神州通用数据库. 一.准备 下载whl及dll: 链接: https://pan.b ...
- ltp的简单学习
ltp的简单学习 简介 下载地址为: https://github.com/linux-test-project/ltp Linux Test Project is a joint project s ...
- zabbix基于容器化在UOS1050E上面的安装与使用
前言 想着能够监控一下操作系统的日志. 因为国产化的需求, 所以我这边使用了UOS1050E 安装zabbix时多次提示缺少php-json 或者是缺少一些libevent等组件. 自己尝试进行解决发 ...
- Nginx 大并发 调优设置
为了性能测试,放弃部分功能,保证绝对性能. 注意可能不能用于生产环境. 下面开始简单讲解. 1. worker_processes 工作线程数. 发现不用太多 一定不能多于操作系统的CPU核数. 2. ...
- 范德蒙德矩阵行列式 & 循环矩阵行列式的证明
范德蒙德矩阵的行列式 \[\begin{vmatrix} 1 & 1 & 1 & \dots & 1 \\ x_1 & x_2 & x_3 & ...
- 【JS 逆向百例】网洛者反爬练习平台第五题:控制台反调试
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...
- ILRuntime性能测试
我们公司有一个Unity原生开发语言C#写的项目,目前已经在安卓测试过多次,上架IOS在考虑热更,所以对ILRuntim进行性能测试,在测试过程中已经按照官方文档进行了CLR绑定和生成Release的 ...
- errgroup的常见误用
errgroup想必稍有经验的golang程序员都应该听说过,实际项目中用过的也应该不在少数.它和sync.WaitGroup类似,都可以发起执行并等待一组协程直到所有协程运行结束.除此之外errgr ...
- C++ Boost 文件系统相关函数
基础处理 #include <iostream> #include <boost/foreach.hpp> #include <boost/filesystem.hpp& ...