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());
}

}
}

相关文章
|
7月前
|
XML Java 数据库连接
解码Java SPI:深入理解与实践【七】
解码Java SPI:深入理解与实践【七】
64 0
|
3月前
|
Java 数据库连接 数据库
Java服务提供接口(SPI)的设计与应用剖析
Java SPI提供了一种优雅的服务扩展和动态加载机制,使得Java应用程序可以轻松地扩展功能和替换组件。通过合理的设计与应用,SPI可以大大增强Java应用的灵活性和可扩展性。
74 18
|
4月前
|
Dubbo Java 关系型数据库
Java SPI机制分析
文章深入分析了Java SPI机制,以JDBC为例,详细探讨了服务提供者接口的发现、加载过程,并提供了一个序列化服务的实战示例,展示了如何使用ServiceLoader进行服务发现和扩展。
34 3
|
4月前
|
Java 开发者
Java SPI机制大揭秘:动态加载服务提供者,一文让你彻底解锁!
【8月更文挑战第25天】Java SPI(服务提供者接口)是一种强大的扩展机制,允许程序在运行时动态加载服务实现。本文首先介绍SPI的基本原理——定义接口并通过配置文件指定其实现类,随后通过示例演示其实现过程。接着,对比分析了SPI与反射及插件机制的不同之处,强调SPI在灵活性与扩展性方面的优势。最后,基于不同场景推荐合适的选择策略,帮助读者深入理解并有效利用SPI机制。
116 1
|
4月前
|
开发者 C# 自然语言处理
WPF开发者必读:掌握多语言应用程序开发秘籍,带你玩转WPF国际化支持!
【8月更文挑战第31天】随着全球化的加速,开发多语言应用程序成为趋势。WPF作为一种强大的图形界面技术,提供了优秀的国际化支持,包括资源文件存储、本地化处理及用户界面元素本地化。本文将介绍WPF国际化的实现方法,通过示例代码展示如何创建和绑定资源文件,并设置应用程序语言环境,帮助开发者轻松实现多语言应用开发,满足不同地区用户的需求。
76 0
|
5月前
|
Java Spring 容器
Java中套路和实现问题之基于SPI机制的套路有哪些关键点
Java中套路和实现问题之基于SPI机制的套路有哪些关键点
|
4月前
|
Java 数据库连接 API
Java 的 SPI 机制
Java 的 SPI 机制
34 0
|
6月前
|
监控 Dubbo Java
深入理解Java SPI:服务发现与扩展的利器(一)
深入理解Java SPI:服务发现与扩展的利器(一)
|
7月前
|
Java 关系型数据库 MySQL
【Java——SPI机制详解】
SPI(Service Provider Interface),是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是 解耦。 当服务的提供者提供了一种接口的实现之后,需要在classpath下的META-INF/services/目录里创建一个以服务接口命名的
163 1
|
Java 数据库连接 开发者
玩转Java面试-什么是Java的SPI机制?
Java的SPI(Service Provider Interface)机制是一种面向接口编程的扩展机制,用于在运行时动态加载实现类。