java中SPI服務(wù)提供者的接口使用總結(jié)
一:什么是SPI
SPI:“服務(wù)提供者的接口”,是一種服務(wù)發(fā)現(xiàn)機制
用于實現(xiàn)框架或庫的擴展點,允許在運行時動態(tài)地插入或更換組件實現(xiàn)。
它提供了一個框架(JDK1.6后ServiceLoader)來發(fā)現(xiàn)和加載服務(wù)實現(xiàn),使得軟件模塊能夠靈活地選擇和使用不同的服務(wù)提供商。

在java中通俗講就是:
- 對框架或第三方j(luò)ar包提供者來說可制定規(guī)范,提供給開發(fā)者可擴展性
- 對開發(fā)者來說可以根據(jù)需要輕松替換框架或第三方j(luò)ar包中提供了SPI機制的接口的實現(xiàn)
在AJ-Captcha與Nacos中均提供了SPI擴展。
二:java SPI示例
1.SPI服務(wù)提供方
SPI服務(wù)提供方架構(gòu)圖:

定義接口規(guī)范:
public interface SpiService {
/**
* 呼叫方式
*/
void call();
}
加載具體的服務(wù)實現(xiàn):
package com.lmy.config;
import com.lmy.service.SpiService;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
/**
* @author : lmy
* @date : 2024/9/14 上午 11:35
* 加載具體的服務(wù)實現(xiàn)
*/
public class SpiServiceLoader {
private static volatile SpiServiceLoader LOADER;
private final SpiService spiService;
private final List<SpiService> spiServiceList;
/**
* 加載服務(wù)
* */
private SpiServiceLoader() {
ServiceLoader<SpiService> loader = ServiceLoader.load(SpiService.class);
List<SpiService> list = new ArrayList<>();
for (SpiService spiService : loader) {
list.add(spiService);
}
spiServiceList = list;
if (!list.isEmpty()) {
// 取第一個
spiService = list.get(0);
} else {
spiService = null;
}
}
/**
* SpiServiceLoader 單例加載
* */
public static SpiServiceLoader getLOADER() {
if (LOADER == null) {
synchronized (SpiServiceLoader.class) {
if (LOADER == null) {
LOADER = new SpiServiceLoader();
}
}
}
return LOADER;
}
public void call(){
if(spiServiceList.isEmpty()){
System.out.println("SpiService服務(wù)未加載!");
}else {
SpiService spiService = spiServiceList.get(0);
spiService.call();
}
}
}
默認實現(xiàn):
package com.lmy.service.impl;
import com.lmy.service.SpiService;
/**
* @author : lmy
* @date : 2024/9/14 上午 10:58
* 默認實現(xiàn)
*/
public class SpiServiceImpl implements SpiService {
@Override
public void call() {
System.out.println("默認手機呼叫");
}
}
指定服務(wù)實現(xiàn)方式:
須在resource下創(chuàng)建META-INF.services,文件名為接口全限定類名,配置為需要被加載的接口實現(xiàn)類的全限定類名

com.lmy.service.impl.SpiServiceImpl
項目打包發(fā)布本地:

2.SPI服務(wù)應用方開發(fā)者
開發(fā)者引入jar包使用服務(wù):
<dependency>
<groupId>com.lmy</groupId>
<artifactId>SPI-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
package com.lmy.Spi;
import com.lmy.config.SpiServiceLoader;
import org.junit.Test;
/**
* @author : lmy
* @date : 2024/9/14 上午 11:48
*/
public class SpiTest {
@Test
public void spiTest () {
SpiServiceLoader loader = SpiServiceLoader.getLOADER();
loader.call();
}
}
執(zhí)行結(jié)果:

開發(fā)者根據(jù)需要擴展替換為自己的服務(wù)實現(xiàn):
package com.lmy.Spi.service;
import com.lmy.service.SpiService;
/**
* @author : lmy
* @date : 2024/9/14 下午 2:09
*/
public class SpiServiceNewImpl implements SpiService {
@Override
public void call() {
System.out.println("衛(wèi)星直呼");
}
}

com.lmy.Spi.service.SpiServiceNewImpl
執(zhí)行結(jié)果:

三:JavaSPI 機制的核心-ServiceLoader
上面代碼可見是通過ServiceLoader 去加載具體的服務(wù)實現(xiàn)的

ServiceLoader 是從JDK1.6 開始提供的一個類,用于加載服務(wù)提供者。
進入源碼可見:
其中 String PREFIX = “META-INF/services/”;
這個就是JDK的SPI功能規(guī)定的具體服務(wù)實現(xiàn)的配置信息文件所在的目錄 META-INF/services/

JDK的SPI規(guī)定 服務(wù)實現(xiàn)者需要在 META-INF/services/ 目錄下 新建文件名為 SPI接口全限定類名的文件
文件內(nèi)容為 服務(wù)實現(xiàn)者需要被加載的具體類的全限定類名
到此這篇關(guān)于java中SPI服務(wù)提供者的接口使用總結(jié)的文章就介紹到這了,更多相關(guān)java spi詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus多表聯(lián)合查詢并且分頁(3表聯(lián)合)
這篇文章主要介紹了MyBatis-Plus多表聯(lián)合查詢并且分頁(3表聯(lián)合),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
SpringCloud網(wǎng)關(guān)組件zuul實例解析
這篇文章主要介紹了SpringCloud網(wǎng)關(guān)組件zuul實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03
SpringCloud Zuul在何種情況下使用Hystrix及問題小結(jié)
這篇文章主要介紹了SpringCloud Zuul在何種情況下使用Hystrix 及問題小結(jié),感興趣的朋友跟隨小編一起看看吧2018-11-11
idea中使用SonarLint進行代碼規(guī)范檢測及使用方法
這篇文章主要介紹了idea中使用SonarLint進行代碼規(guī)范檢測,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08
使用java實現(xiàn)http多線程斷點下載文件(一)
Java 多線程斷點下載文件基本原理:利用URLConnection獲取要下載文件的長度、頭部等相關(guān)信息,并設(shè)置響應的頭部信息,本文將詳細介紹,需要了解更多的朋友可以參考下2012-12-12
Java實現(xiàn)批量導入excel表格數(shù)據(jù)到數(shù)據(jù)庫中的方法
這篇文章主要介紹了Java實現(xiàn)批量導入excel表格數(shù)據(jù)到數(shù)據(jù)庫中的方法,結(jié)合實例形式詳細分析了java導入Excel數(shù)據(jù)到數(shù)據(jù)庫的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-10-10

