Java 中经常被提到的 SPI 到底是什么?

简介: Java 程序员在日常工作中经常会听到 SPI,而且很多框架都使用了 SPI 的技术,那么问题来了,到底什么是 SPI 呢?今天阿粉就带大家好好了解一下 SPI。

Java 程序员在日常工作中经常会听到 SPI,而且很多框架都使用了 SPI 的技术,那么问题来了,到底什么是 SPI 呢?今天阿粉就带大家好好了解一下 SPI。

SPI 概念
SPI 全称是 Service Provider Interface,是一种 JDK 内置的动态加载实现扩展点的机制,通过 SPI 技术我们可以动态获取接口的实现类,不用自己来创建。

这里提到了接口和实现类,那么 SPI 技术上具体有哪些技术细节呢?

接口:需要有一个功能接口;
实现类:接口只是规范,具体的执行需要有实现类才行,所以不可缺少的需要有实现类;
配置文件:要实现 SPI 机制,必须有一个与接口同名的文件存放于类路径下面的 META-INF/services 文件夹中,并且文件中的每一行的内容都是一个实现类的全路径;
类加载器 ServiceLoader:JDK 内置的一个类加载器,用于加载配置文件中的实现类;
举个栗子
上面说了 SPI 的几个概念,接下来阿粉就通过一个栗子来带大家感受一下具体的用法。

第一步
创建一个接口,这里我们创建一个解压缩的接口,其中定义了压缩和解压的两个方法。

package com.example.demo.spi;

/**


  • Function:
  • Author:@author ziyou
  • Date:2022-10-08 21:31
  • Desc:

*/
public interface Compresser {
byte[] compress(byte[] bytes);
byte[] decompress(byte[] bytes);
}
复制代码
第二步
再写两个对应的实现类,分别是 GzipCompresser.java 和 WinRarCompresser.java 代码如下

package com.example.demo.spi.impl;

import com.example.demo.spi.Compresser;

import java.nio.charset.StandardCharsets;

/**


  • Function:
  • Author:@author ziyou
  • Date:2022-10-08 21:33
  • Desc:

*/
public class GzipCompresser implements Compresser {
@Override
public byte[] compress(byte[] bytes) {

return"compress by Gzip".getBytes(StandardCharsets.UTF_8);

}
@Override
public byte[] decompress(byte[] bytes) {

return "decompress by Gzip".getBytes(StandardCharsets.UTF_8);

}
}
复制代码
package com.example.demo.spi.impl;

import com.example.demo.spi.Compresser;

import java.nio.charset.StandardCharsets;

/**


  • Function:
  • Author:@author ziyou
  • Date:2022-10-08 21:33
  • Desc:

*/
public class WinRarCompresser implements Compresser {
@Override
public byte[] compress(byte[] bytes) {

return "compress by WinRar".getBytes(StandardCharsets.UTF_8);

}

@Override
public byte[] decompress(byte[] bytes) {

return "decompress by WinRar".getBytes(StandardCharsets.UTF_8);

}
}

复制代码
第三步
创建配置文件,我们接着在 resources 目录下创建一个名为 META-INF/services 的文件夹,在其中创建一个名为 com.example.demo.spi.Compresser 的文件,其中的内容如下:

com.example.demo.spi.impl.WinRarCompresser
com.example.demo.spi.impl.GzipCompresser
复制代码
注意该文件的名称必须是接口的全路径,文件里面的内容每一行都是一个实现类的全路径,多个实现类就写在多行里面,效果如下。

11.png

第四步
有了上面的接口,实现类和配置文件,接下来我们就可以使用 ServiceLoader 动态加载实现类,来实现 SPI 技术了,如下所示:

package com.example.demo;

import com.example.demo.spi.Compresser;

import java.nio.charset.StandardCharsets;
import java.util.ServiceLoader;

public class TestSPI {
public static void main(String[] args) {

ServiceLoader<Compresser> compressers = ServiceLoader.load(Compresser.class);
for (Compresser compresser : compressers) {
  System.out.println(compresser.getClass());
}

}
}

相关文章
|
3月前
|
XML Java 数据库连接
解码Java SPI:深入理解与实践【七】
解码Java SPI:深入理解与实践【七】
30 0
|
4月前
|
Java 关系型数据库 MySQL
JAVA 特性 SPI 机制
在面向对象编程中,基于开闭原则和解耦的需要,一般建议用接口进行模块之间通信编程,通常情况下调用方模块是不会感知到被调用方模块的内部具体实现。 为了实现在模块装配的时候不用在程序里面动态指明,这就需要一种服务发现机制。Java SPI就是提供了这样一个机制:为某个接口寻找服务实现的机制。这有点类似IoC的思想,将装配的控制权移交到了程序之外。 SPI(Service Provider Interface),是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件。
|
10月前
|
Java 数据库连接 开发者
玩转Java面试-什么是Java的SPI机制?
Java的SPI(Service Provider Interface)机制是一种面向接口编程的扩展机制,用于在运行时动态加载实现类。
|
5月前
|
Dubbo Java 应用服务中间件
从源码全面解析 Java SPI 的来龙去脉
从源码全面解析 Java SPI 的来龙去脉
|
5月前
|
安全 Dubbo Java
[Java 晋级之路] 框架、中间件等领域都在使用,你还不快来学习Java SPI机制?!
[Java 晋级之路] 框架、中间件等领域都在使用,你还不快来学习Java SPI机制?!
|
6月前
|
Dubbo Java 应用服务中间件
阿里一面:说一说Java、Spring、Dubbo三者SPI机制的原理和区别
大家好,我是三友~~ 今天来跟大家聊一聊Java、Spring、Dubbo三者SPI机制的原理和区别。 其实我之前写过一篇类似的文章,但是这篇文章主要是剖析dubbo的SPI机制的源码,中间只是简单地介绍了一下Java、Spring的SPI机制,并没有进行深入,所以本篇就来深入聊一聊这三者的原理和区别。
|
7月前
|
设计模式 Java 关系型数据库
JAVA设计模式第十讲:SPI - 业务差异解决方案
JAVA设计模式第十讲:SPI - 业务差异解决方案
JAVA设计模式第十讲:SPI - 业务差异解决方案
|
8月前
|
缓存 Java API
SPI 在 Java 中的实现与应用
sharding-jdbc 是一款用于分库分表的中间件,在数据库分布式场景中,为了保证数据库主键的唯一性,会采取相应的主键生成策略,而主键生成策略有很多种实现。sharding-jdbc 在主键生成策略使用了 SPI 进行装配。
38 0
|
8月前
|
Dubbo Java 应用服务中间件
「Java面试」荃网讲的蕞好的SPI机制,什么是Java SPI它有什么作用
很多主流框架都用到了SPI机制,比如Dubbo、Spring都有用到,可能很多小伙伴也听说过。今天给大家来聊一聊什么是SPI,它用什么作用?
43 0
|
9月前
|
Java 关系型数据库 MySQL
Java SPI机制的原理和实践
SPI 全称 Service Provider Interface,是 Java 提供的,旨在由第三方实现或扩展的 API,它是一种用于动态加载服务的机制。Java 中 SPI 机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。
176 0