Dubbo SPI

Java SPI

SPI全稱Service Provider Interface,是Java提供的一套用來被第三方實(shí)現(xiàn)或者擴(kuò)展的接口,它可以用來啟用框架擴(kuò)展和替換組件。 SPI的作用就是為這些被擴(kuò)展的API尋找服務(wù)實(shí)現(xiàn)。

原因

面向的對(duì)象的設(shè)計(jì)里,我們一般推薦模塊之間基于接口編程,模塊之間不對(duì)實(shí)現(xiàn)類進(jìn)行硬編碼。一旦代碼里涉及具體的實(shí)現(xiàn)類,就違反了可拔插的原則,如果需要替換一種實(shí)現(xiàn),就需要修改代碼。為了實(shí)現(xiàn)在模塊裝配的時(shí)候不用在程序里動(dòng)態(tài)指明,這就需要一種服務(wù)發(fā)現(xiàn)機(jī)制。java spi就是提供這樣的一個(gè)機(jī)制:為某個(gè)接口尋找服務(wù)實(shí)現(xiàn)的機(jī)制。這有點(diǎn)類似IOC的思想,將裝配的控制權(quán)移到了程序之外。

API SPI

  • API (Application Programming Interface)在大多數(shù)情況下,都是實(shí)現(xiàn)方制定接口并完成對(duì)接口的實(shí)現(xiàn),調(diào)用方僅僅依賴接口調(diào)用,且無權(quán)選擇不同實(shí)現(xiàn)。 從使用人員上來說,API 直接被應(yīng)用開發(fā)人員使用。

  • SPI (Service Provider Interface)是調(diào)用方來制定接口規(guī)范,提供給外部來實(shí)現(xiàn),調(diào)用方在調(diào)用時(shí)則選擇自己需要的外部實(shí)現(xiàn)。 從使用人員上來說,SPI 被框架擴(kuò)展人員使用。

實(shí)現(xiàn)

  • 定義接口
  • 編寫實(shí)現(xiàn)類
  • 在resources目錄下新建META-INF/services目錄,并且在這個(gè)目錄下新建一個(gè)與上述接口的全限定名一致的文件,在這個(gè)文件中寫入接口的實(shí)現(xiàn)類的全限定名
    比如接口全限定名:com.spi.cache.Cache
    文件內(nèi)容:
    com.spi.cache.LocalCache
    com.spi.cache.RedisCache
  • 最后調(diào)用ServiceLoader.load(UploadCDN.class)即可加載出以上兩個(gè)實(shí)現(xiàn)類

原理

Class.forName反射加載并實(shí)例化進(jìn)緩存

缺點(diǎn)

Java SPI 在查找擴(kuò)展實(shí)現(xiàn)類的時(shí)候遍歷 SPI 的配置文件并且將實(shí)現(xiàn)類全部實(shí)例化,無法按需加載

Dubbo SPI

image.png

優(yōu)點(diǎn)

Dubbo 的擴(kuò)展點(diǎn)加載是基于JDK 標(biāo)準(zhǔn)的 SPI 擴(kuò)展點(diǎn)發(fā)現(xiàn)機(jī)制增強(qiáng)而來的,Dubbo 改進(jìn)了 JDK 標(biāo)準(zhǔn)的 SPI 的以下問題:

  • JDK 標(biāo)準(zhǔn)的 SPI 會(huì)一次性實(shí)例化擴(kuò)展點(diǎn)所有實(shí)現(xiàn),如果有擴(kuò)展實(shí)現(xiàn)初始化很耗時(shí),但如果沒用上也加載,會(huì)很浪費(fèi)資源。

  • 如果擴(kuò)展點(diǎn)加載失敗,就失敗了,給用戶沒有任何通知。比如:JDK 標(biāo)準(zhǔn)的ScriptEngine,如果Ruby ScriptEngine 因?yàn)樗蕾嚨?jruby.jar 不存在,導(dǎo)致 Ruby ScriptEngine 類加載失敗,這個(gè)失敗原因被吃掉了,當(dāng)用戶執(zhí)行 ruby 腳本時(shí),會(huì)報(bào)空指針異常,而不是報(bào)Ruby ScriptEngine不存在。

  • 增加了對(duì)擴(kuò)展點(diǎn) IoC 和 AOP 的支持,一個(gè)擴(kuò)展點(diǎn)可以直接 setter 注入其它擴(kuò)展點(diǎn)。

配置文件

文件名同樣是接口全限定名,而內(nèi)容是k-v形式,比如localCache=com.spi.cache.LocalCache,同樣這樣的方式實(shí)現(xiàn)按需加載

注解

@SPI注解(注解在類上)

標(biāo)識(shí)了接口是一個(gè)擴(kuò)展點(diǎn),屬性 value 用來指定默認(rèn)適配擴(kuò)展點(diǎn)的名稱。

@Adaptive注解(注解在類型和方法上)

注解在類上 , 這個(gè)類就是缺省的適配擴(kuò)展;注解在擴(kuò)展點(diǎn) @SPI 的方法上時(shí) , dubbo 動(dòng)態(tài)的生成一個(gè)這個(gè)擴(kuò)展點(diǎn)的適配擴(kuò)展類

@Activate注解 - 自適應(yīng)擴(kuò)展(注解在類型和方法上)

注解在擴(kuò)展點(diǎn)的實(shí)現(xiàn)類上 ,表示了一個(gè)擴(kuò)展類被獲取到的的條件,根據(jù) @Activate 中的 group 、 value 屬性來過濾,

文件目錄

  • META-INF/services/ 目錄:該目錄下的 SPI 配置文件是為了用來兼容 Java SPI 。
  • META-INF/dubbo/ 目錄:該目錄存放用戶自定義的 SPI 配置文件。
  • META-INF/dubbo/internal/ 目錄:該目錄存放 Dubbo 內(nèi)部使用的 SPI 配置文件。

AOP

https://www.cnblogs.com/UYGHYTYH/p/13028591.html

image.png

利用符合構(gòu)造函數(shù)要求的裝飾者模式包裝類來包裝實(shí)現(xiàn)類

IOC

一個(gè)擴(kuò)展點(diǎn)可以通過 setter 注入其它擴(kuò)展點(diǎn)

原理

ExtensionLoader類似 Java SPI 中 ServiceLoader

  • getExtension():主要用于獲取名稱為name的對(duì)應(yīng)的子類的對(duì)象,這里如果子類對(duì)象如果有AOP相關(guān)的配置,這里也會(huì)對(duì)其進(jìn)行封裝;
  • getAdaptiveExtension():使用定義的裝飾類來封裝目標(biāo)子類,具體使用哪個(gè)子類可以在定義的裝飾類中通過一定的條件進(jìn)行配置;
  • getExtensionLoader():加載當(dāng)前接口的子類并且實(shí)例化一個(gè)ExtensionLoader對(duì)象。

使用:ExtensionLoader.getExtensionLoader(Cache.class).getExtension()或其他方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄:關(guān)于 Java SPI實(shí)現(xiàn) Java SPI 需要遵循的標(biāo)準(zhǔn)Java SPI 的實(shí)際應(yīng)用Java SPI 的...
    Carol_6a27閱讀 466評(píng)論 0 0
  • 從上一篇 Java SPI 機(jī)制解析 可以知道 Java SPI 的一些劣勢(shì)。Dubbo 的擴(kuò)展點(diǎn)加載從 Java...
    匠丶閱讀 4,304評(píng)論 0 7
  • SPI簡介 站在一個(gè)框架作者的角度來說,定義一個(gè)接口,自己默認(rèn)給出幾個(gè)接口的實(shí)現(xiàn)類,同時(shí) 允許框架的使用者也能夠自...
    fffhJk閱讀 594評(píng)論 0 1
  • 開篇 ?SPI全稱為Service Provider Interface,是一種服務(wù)提供機(jī)制,比如在現(xiàn)實(shí)中我們經(jīng)常...
    晴天哥_王志閱讀 2,973評(píng)論 4 13
  • 最近拜讀dubbo 的源碼,其構(gòu)架設(shè)計(jì)是很精彩,基于插件式的構(gòu)架方式,靈活性可見一般。此外dubbo 框架難得基 ...
    Double_winter閱讀 1,104評(píng)論 0 0

友情鏈接更多精彩內(nèi)容