java中SPI服務(wù)提供者的接口使用總結(jié)
一:什么是SPI
SPI:“服務(wù)提供者的接口”,是一種服務(wù)發(fā)現(xiàn)機(jī)制
用于實(shí)現(xiàn)框架或庫(kù)的擴(kuò)展點(diǎn),允許在運(yùn)行時(shí)動(dòng)態(tài)地插入或更換組件實(shí)現(xiàn)。
它提供了一個(gè)框架(JDK1.6后ServiceLoader)來(lái)發(fā)現(xiàn)和加載服務(wù)實(shí)現(xiàn),使得軟件模塊能夠靈活地選擇和使用不同的服務(wù)提供商。
在java中通俗講就是:
- 對(duì)框架或第三方j(luò)ar包提供者來(lái)說(shuō)可制定規(guī)范,提供給開(kāi)發(fā)者可擴(kuò)展性
- 對(duì)開(kāi)發(fā)者來(lái)說(shuō)可以根據(jù)需要輕松替換框架或第三方j(luò)ar包中提供了SPI機(jī)制的接口的實(shí)現(xiàn)
在AJ-Captcha與Nacos中均提供了SPI擴(kuò)展。
二:java SPI示例
1.SPI服務(wù)提供方
SPI服務(wù)提供方架構(gòu)圖:
定義接口規(guī)范:
public interface SpiService { /** * 呼叫方式 */ void call(); }
加載具體的服務(wù)實(shí)現(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ù)實(shí)現(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()) { // 取第一個(gè) 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(); } } }
默認(rèn)實(shí)現(xiàn):
package com.lmy.service.impl; import com.lmy.service.SpiService; /** * @author : lmy * @date : 2024/9/14 上午 10:58 * 默認(rèn)實(shí)現(xiàn) */ public class SpiServiceImpl implements SpiService { @Override public void call() { System.out.println("默認(rèn)手機(jī)呼叫"); } }
指定服務(wù)實(shí)現(xiàn)方式:
須在resource下創(chuàng)建META-INF.services,文件名為接口全限定類(lèi)名,配置為需要被加載的接口實(shí)現(xiàn)類(lèi)的全限定類(lèi)名
com.lmy.service.impl.SpiServiceImpl
項(xiàng)目打包發(fā)布本地:
2.SPI服務(wù)應(yīng)用方開(kāi)發(fā)者
開(kāi)發(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é)果:
開(kāi)發(fā)者根據(jù)需要擴(kuò)展替換為自己的服務(wù)實(shí)現(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 機(jī)制的核心-ServiceLoader
上面代碼可見(jiàn)是通過(guò)ServiceLoader 去加載具體的服務(wù)實(shí)現(xiàn)的
ServiceLoader 是從JDK1.6 開(kāi)始提供的一個(gè)類(lèi),用于加載服務(wù)提供者。
進(jìn)入源碼可見(jiàn):
其中 String PREFIX = “META-INF/services/”;
這個(gè)就是JDK的SPI功能規(guī)定的具體服務(wù)實(shí)現(xiàn)的配置信息文件所在的目錄 META-INF/services/
JDK的SPI規(guī)定 服務(wù)實(shí)現(xiàn)者需要在 META-INF/services/ 目錄下 新建文件名為 SPI接口全限定類(lèi)名的文件
文件內(nèi)容為 服務(wù)實(shí)現(xiàn)者需要被加載的具體類(lèi)的全限定類(lèi)名
到此這篇關(guān)于java中SPI服務(wù)提供者的接口使用總結(jié)的文章就介紹到這了,更多相關(guān)java spi詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus多表聯(lián)合查詢并且分頁(yè)(3表聯(lián)合)
這篇文章主要介紹了MyBatis-Plus多表聯(lián)合查詢并且分頁(yè)(3表聯(lián)合),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08struts中動(dòng)態(tài)方法調(diào)用使用通配符
這篇文章主要介紹了struts中動(dòng)態(tài)方法調(diào)用使用通配符的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-09-09SpringCloud網(wǎng)關(guān)組件zuul實(shí)例解析
這篇文章主要介紹了SpringCloud網(wǎng)關(guān)組件zuul實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03SpringCloud Zuul在何種情況下使用Hystrix及問(wèn)題小結(jié)
這篇文章主要介紹了SpringCloud Zuul在何種情況下使用Hystrix 及問(wèn)題小結(jié),感興趣的朋友跟隨小編一起看看吧2018-11-11idea中使用SonarLint進(jìn)行代碼規(guī)范檢測(cè)及使用方法
這篇文章主要介紹了idea中使用SonarLint進(jìn)行代碼規(guī)范檢測(cè),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08使用java實(shí)現(xiàn)http多線程斷點(diǎn)下載文件(一)
Java 多線程斷點(diǎn)下載文件基本原理:利用URLConnection獲取要下載文件的長(zhǎng)度、頭部等相關(guān)信息,并設(shè)置響應(yīng)的頭部信息,本文將詳細(xì)介紹,需要了解更多的朋友可以參考下2012-12-12Java實(shí)現(xiàn)批量導(dǎo)入excel表格數(shù)據(jù)到數(shù)據(jù)庫(kù)中的方法
這篇文章主要介紹了Java實(shí)現(xiàn)批量導(dǎo)入excel表格數(shù)據(jù)到數(shù)據(jù)庫(kù)中的方法,結(jié)合實(shí)例形式詳細(xì)分析了java導(dǎo)入Excel數(shù)據(jù)到數(shù)據(jù)庫(kù)的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-10-10