0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

JDK內(nèi)置的一種服務(wù)SPI機(jī)制

jf_ro2CN3Fa ? 來(lái)源:稀土掘金 ? 2023-02-15 09:15 ? 次閱讀

SPI(Service Provider Interface)是JDK內(nèi)置的一種服務(wù)提供發(fā)現(xiàn)機(jī)制,可以用來(lái)啟用框架擴(kuò)展和替換組件,主要用于框架中開(kāi)發(fā),例如Dubbo、Spring、Common-Logging,JDBC等采用采用SPI機(jī)制,針對(duì)同一接口采用不同的實(shí)現(xiàn)提供給不同的用戶(hù),從而提高了框架的擴(kuò)展性。

Java SPI實(shí)現(xiàn)

Java內(nèi)置的SPI通過(guò)java.util.ServiceLoader類(lèi)解析classPath和jar包的META-INF/services/目錄 下的以接口全限定名命名的文件,并加載該文件中指定的接口實(shí)現(xiàn)類(lèi),以此完成調(diào)用。

示例說(shuō)明

創(chuàng)建動(dòng)態(tài)接口

publicinterfaceVedioSPI
{
voidcall();
}

實(shí)現(xiàn)類(lèi)1

publicclassMp3VedioimplementsVedioSPI
{
@Override
publicvoidcall()
{
System.out.println("thisismp3call");
}

}

實(shí)現(xiàn)類(lèi)2

publicclassMp4VedioimplementsVedioSPI
{
@Override
publicvoidcall()
{
System.out.println("thisismp4call");
}

}

在項(xiàng)目的source目錄下新建META-INF/services/目錄下,創(chuàng)建com.skywares.fw.juc.spi.VedioSPI文件。

2dc32b86-ac5d-11ed-bfe3-dac502259ad0.png

相關(guān)測(cè)試

publicclassVedioSPITest
{
publicstaticvoidmain(String[]args)
{
ServiceLoaderserviceLoader=ServiceLoader.load(VedioSPI.class);

serviceLoader.forEach(t->{
t.call();
});
}
}

說(shuō)明:Java實(shí)現(xiàn)spi是通過(guò)ServiceLoader來(lái)查找服務(wù)提供的工具類(lèi)。

運(yùn)行結(jié)果:

2dd556f8-ac5d-11ed-bfe3-dac502259ad0.png

源碼分析

上述只是通過(guò)簡(jiǎn)單的示例來(lái)實(shí)現(xiàn)下java的內(nèi)置的SPI功能。其實(shí)現(xiàn)原理是ServiceLoader是Java內(nèi)置的用于查找服務(wù)提供接口的工具類(lèi),通過(guò)調(diào)用load()方法實(shí)現(xiàn)對(duì)服務(wù)提供接口的查找,最后遍歷來(lái)逐個(gè)訪(fǎng)問(wèn)服務(wù)提供接口的實(shí)現(xiàn)類(lèi)。

2de67e92-ac5d-11ed-bfe3-dac502259ad0.png

從源碼可以發(fā)現(xiàn):

ServiceLoader類(lèi)本身實(shí)現(xiàn)了Iterable接口并實(shí)現(xiàn)了其中的iterator方法,iterator方法的實(shí)現(xiàn)中調(diào)用了LazyIterator這個(gè)內(nèi)部類(lèi)中的方法,迭代器創(chuàng)建實(shí)例。

所有服務(wù)提供接口的對(duì)應(yīng)文件都是放置在META-INF/services/目錄下,final類(lèi)型決定了PREFIX目錄不可變更。

雖然java提供的SPI機(jī)制的思想非常好,但是也存在相應(yīng)的弊端。具體如下:

Java內(nèi)置的方法方式只能通過(guò)遍歷來(lái)獲取

服務(wù)提供接口必須放到META-INF/services/目錄下。

針對(duì)java的spi存在的問(wèn)題,Spring的SPI機(jī)制沿用的SPI的思想,但對(duì)其進(jìn)行擴(kuò)展和優(yōu)化。

Spring SPI

Spring SPI沿用了Java SPI的設(shè)計(jì)思想,Spring采用的是spring.factories方式實(shí)現(xiàn)SPI機(jī)制,可以在不修改Spring源碼的前提下,提供Spring框架的擴(kuò)展性。

Spring 示例

定義接口

publicinterfaceDataBaseSPI
{
voidgetConnection();
}

相關(guān)實(shí)現(xiàn)

##DB2實(shí)現(xiàn)
publicclassDB2DataBaseimplementsDataBaseSPI
{
@Override
publicvoidgetConnection()
{
System.out.println("thisdatabaseisdb2");
}

}

##Mysql實(shí)現(xiàn)
publicclassMysqlDataBaseimplementsDataBaseSPI
{
@Override
publicvoidgetConnection()
{
System.out.println("thisismysqldatabase");
}

}

1、在項(xiàng)目的META-INF目錄下,新增spring.factories文件

2df71af4-ac5d-11ed-bfe3-dac502259ad0.png

2、填寫(xiě)相關(guān)的接口信息,內(nèi)容如下:

com.skywares.fw.juc.springspi.DataBaseSPI=com.skywares.fw.juc.springspi.DB2DataBase,com.skywares.fw.juc.springspi.MysqlDataBase

說(shuō)明多個(gè)實(shí)現(xiàn)采用逗號(hào)分隔。

相關(guān)測(cè)試類(lèi)

publicclassSpringSPITest
{
publicstaticvoidmain(String[]args)
{
ListdataBaseSPIs=SpringFactoriesLoader.loadFactories(DataBaseSPI.class,
Thread.currentThread().getContextClassLoader());

for(DataBaseSPIdatBaseSPI:dataBaseSPIs){
datBaseSPI.getConnection();
}
}
}

輸出結(jié)果

2e061d9c-ac5d-11ed-bfe3-dac502259ad0.png

從示例中我們看出,Spring 采用spring.factories實(shí)現(xiàn)SPI與java實(shí)現(xiàn)SPI非常相似,但是spring的spi方式針對(duì)java的spi進(jìn)行的相關(guān)優(yōu)化具體內(nèi)容如下:

Java SPI是一個(gè)服務(wù)提供接口對(duì)應(yīng)一個(gè)配置文件,配置文件中存放當(dāng)前接口的所有實(shí)現(xiàn)類(lèi),多個(gè)服務(wù)提供接口對(duì)應(yīng)多個(gè)配置文件,所有配置都在services目錄下;

Spring factories SPI是一個(gè)spring.factories配置文件存放多個(gè)接口及對(duì)應(yīng)的實(shí)現(xiàn)類(lèi),以接口全限定名作為key,實(shí)現(xiàn)類(lèi)作為value來(lái)配置,多個(gè)實(shí)現(xiàn)類(lèi)用逗號(hào)隔開(kāi),僅spring.factories一個(gè)配置文件。

那么spring是如何通過(guò)加載spring.factories來(lái)實(shí)現(xiàn)SpI的呢?我們可以通過(guò)源碼來(lái)進(jìn)一步分析。

源碼分析

2e1b1332-ac5d-11ed-bfe3-dac502259ad0.png

說(shuō)明:loadFactoryNames解析spring.factories文件中指定接口的實(shí)現(xiàn)類(lèi)的全限定名,具體實(shí)現(xiàn)如下:

2e312384-ac5d-11ed-bfe3-dac502259ad0.png

說(shuō)明:獲取所有jar包中META-INF/spring.factories文件路徑,以枚舉值返回。遍歷spring.factories文件路徑,逐個(gè)加載解析,整合factoryClass類(lèi)型的實(shí)現(xiàn)類(lèi)名稱(chēng),獲取到實(shí)現(xiàn)類(lèi)的全類(lèi)名稱(chēng)后進(jìn)行類(lèi)的實(shí)例話(huà)操作,其相關(guān)源碼如下:

2e4bdbb6-ac5d-11ed-bfe3-dac502259ad0.png

說(shuō)明:實(shí)例化是通過(guò)反射來(lái)實(shí)現(xiàn)對(duì)應(yīng)的初始化。







審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2985

    瀏覽量

    106951
  • SPI
    SPI
    +關(guān)注

    關(guān)注

    17

    文章

    1784

    瀏覽量

    94815
  • JDBC
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    13591

原文標(biāo)題:深入剖析 Spring Boot 的 SPI 機(jī)制

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 0人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    JDK動(dòng)態(tài)代理的原理

    在Java中,動(dòng)態(tài)代理是一種機(jī)制,允許在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建代理對(duì)象來(lái)代替某個(gè)實(shí)際對(duì)象,從而在其前后執(zhí)行額外的邏輯。 為什么JDK動(dòng)態(tài)代理只能代理接口實(shí)現(xiàn)類(lèi),原因是JDK動(dòng)態(tài)代理是基于接口
    的頭像 發(fā)表于 09-30 10:51 ?810次閱讀

    Java的SPI機(jī)制詳解

    作者:京東物流 楊葦葦 1.SPI簡(jiǎn)介 SPI(Service Provicer Interface)是Java語(yǔ)言提供的一種接口發(fā)現(xiàn)機(jī)制,用來(lái)實(shí)現(xiàn)接口和接口實(shí)現(xiàn)的解耦。簡(jiǎn)單來(lái)說(shuō),就是
    的頭像 發(fā)表于 03-05 11:35 ?690次閱讀
    Java的<b class='flag-5'>SPI</b><b class='flag-5'>機(jī)制</b>詳解

    請(qǐng)問(wèn)板子的延遲函數(shù)是一種什么機(jī)制?

    我想請(qǐng)問(wèn)下,你們板子的延遲函數(shù)是一種什么機(jī)制,如以上的定義所示,他的延時(shí)單位是ms還是其他,就像Delay(0x000FFFFF)算是延時(shí)了多少秒?有沒(méi)有相關(guān)的資料視屏什么的講解
    發(fā)表于 10-15 10:40

    怎樣去設(shè)計(jì)一種同步補(bǔ)償機(jī)制(CDCO算法)?

    本文基于發(fā)送方接收方雙向同步算法的原理,提出一種基于時(shí)鐘漂移與偏移的同步補(bǔ)償機(jī)制(CDCO算法)。
    發(fā)表于 05-17 06:18

    分享一種高性能的FM內(nèi)置天線(xiàn)解決方案

    分享一種高性能的FM內(nèi)置天線(xiàn)解決方案
    發(fā)表于 05-26 06:18

    是否有一種機(jī)制可以從虛擬功能處理程序進(jìn)行屏幕轉(zhuǎn)換呢?

    我想知道是否有一種機(jī)制可以根據(jù)在滾動(dòng)列表控件(小部件)上選擇的項(xiàng)目轉(zhuǎn)換到不同的屏幕,并傳遞有關(guān)所選項(xiàng)目或所選滾動(dòng)列表項(xiàng)目的索引的信息,或者是否有一種機(jī)制可以從虛擬功能處理程序進(jìn)行屏幕轉(zhuǎn)
    發(fā)表于 12-13 08:09

    一種基于最優(yōu)網(wǎng)格的動(dòng)態(tài)數(shù)據(jù)過(guò)濾機(jī)制

    數(shù)據(jù)過(guò)濾機(jī)制是數(shù)據(jù)分發(fā)管理的核心,直接影響數(shù)據(jù)分發(fā)管理效率。該文提出一種基于最優(yōu)網(wǎng)格的動(dòng)態(tài)數(shù)據(jù)過(guò)濾機(jī)制,分析網(wǎng)格單元大小與更新區(qū)域網(wǎng)格數(shù)量、冗余信息數(shù)量的關(guān)系
    發(fā)表于 04-14 09:06 ?18次下載

    一種高效的磁盤(pán)隊(duì)列I/O機(jī)制

    分析了傳統(tǒng)磁盤(pán)隊(duì)列的存儲(chǔ)管理開(kāi)銷(xiāo)和讀寫(xiě)性能,針對(duì)磁盤(pán)隊(duì)列I/O已成為影響消息服務(wù)器性能的首要瓶頸,提出了一種高效磁盤(pán)隊(duì)列I/O機(jī)制—FlashQ。FlashQ采用物理上連續(xù)的磁盤(pán)塊
    發(fā)表于 05-14 19:51 ?32次下載

    一種基于市場(chǎng)機(jī)制的隨機(jī)服務(wù)系統(tǒng)模型

             在市場(chǎng)機(jī)制的網(wǎng)格環(huán)境中對(duì)大量的用戶(hù)進(jìn)行有效的排隊(duì)是很有必要的。本文以隨機(jī)服務(wù)系統(tǒng)理論為基礎(chǔ)針對(duì)網(wǎng)格計(jì)算提出了一種基于市場(chǎng)
    發(fā)表于 09-05 08:48 ?16次下載

    一種ad hoc網(wǎng)信任聲譽(yù)評(píng)估機(jī)制

    在Ad hoc 網(wǎng)絡(luò)中,設(shè)計(jì)一種有效的機(jī)制來(lái)確保信息包的有效傳遞是研究重點(diǎn)。本文提出了一種信任聲譽(yù)評(píng)估機(jī)制,不同于以往根據(jù)位置評(píng)估聲譽(yù)和處理惡意節(jié)點(diǎn)散播虛假聲譽(yù)的
    發(fā)表于 09-22 10:24 ?5次下載

    SPI模式下MMC卡的讀寫(xiě)機(jī)制

    SPI模式下MMC卡的讀寫(xiě)機(jī)制  多媒體卡MMC(MultiMedia Card)是由美國(guó)SanDisk公司和德國(guó)Simens公司于1997年共同開(kāi)發(fā)的一種多功能Flash存儲(chǔ)設(shè)備?;贏RM7芯
    發(fā)表于 03-29 15:13 ?1372次閱讀
    <b class='flag-5'>SPI</b>模式下MMC卡的讀寫(xiě)<b class='flag-5'>機(jī)制</b>

    一種通用SPI接口的FPGA設(shè)計(jì)與實(shí)現(xiàn)

    SPI 串行總線(xiàn)是一種常用的標(biāo)準(zhǔn)接口,其使用簡(jiǎn)單方便而且占用系統(tǒng)資源少,應(yīng)用相當(dāng)廣泛。本文將介紹一種新的通用的SPI 總線(xiàn)的FPGA 實(shí)現(xiàn)方法。
    發(fā)表于 09-09 11:58 ?67次下載
    <b class='flag-5'>一種</b>通用<b class='flag-5'>SPI</b>接口的FPGA設(shè)計(jì)與實(shí)現(xiàn)

    一種改進(jìn)的區(qū)塊鏈共識(shí)機(jī)制的研究與實(shí)現(xiàn)

    區(qū)塊鏈作為比特幣的底層技術(shù),是一種通過(guò)去中心化、去信任的方式集體維護(hù)個(gè)可靠數(shù)據(jù)庫(kù)的技術(shù)方案。共識(shí)機(jī)制是區(qū)塊鏈的核心,解決了如何在個(gè)缺乏信任、完全自由開(kāi)放的網(wǎng)絡(luò)中達(dá)成共識(shí)的問(wèn)題。 文
    發(fā)表于 01-10 14:24 ?1次下載
    <b class='flag-5'>一種</b>改進(jìn)的區(qū)塊鏈共識(shí)<b class='flag-5'>機(jī)制</b>的研究與實(shí)現(xiàn)

    可插拔組件設(shè)計(jì)機(jī)制SPI介紹

    SPI 的全稱(chēng)是 Service Provider Interface, 即提供服務(wù)接口;是一種服務(wù)發(fā)現(xiàn)機(jī)制
    的頭像 發(fā)表于 03-23 09:20 ?1406次閱讀

    什么是SPI機(jī)制

    一種服務(wù)提供發(fā)現(xiàn)接口機(jī)制,旨在由第三方服務(wù)實(shí)現(xiàn)或擴(kuò)展為組件,方便開(kāi)發(fā)人員快速集成指定擴(kuò)展組件滿(mǎn)足指定的需求。這
    的頭像 發(fā)表于 10-08 15:03 ?1504次閱讀
    什么是<b class='flag-5'>SPI</b><b class='flag-5'>機(jī)制</b>

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品