免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Dubbo源碼分析—SPI擴(kuò)展

SPI擴(kuò)展

前言

站在一個(gè)框架作者的角度來(lái)說(shuō),定義一個(gè)接口,自己默認(rèn)給出幾個(gè)接口的實(shí)現(xiàn)類,同時(shí) 允許框架的使用者也能夠自定義接口的實(shí)現(xiàn)?,F(xiàn)在一個(gè)簡(jiǎn)單的問題就是:如何優(yōu)雅的根據(jù)一個(gè)接口來(lái)獲取該接口的所有實(shí)現(xiàn)類呢?

JDK SPI 正是為了優(yōu)雅解決這個(gè)問題而生,SPI 全稱為 (Service Provider Interface),即服務(wù)提供商接口,是JDK內(nèi)置的一種服務(wù)提供發(fā)現(xiàn)機(jī)制。目前有不少框架用它來(lái)做服務(wù)的擴(kuò)展發(fā)現(xiàn),簡(jiǎn)單來(lái)說(shuō),它就是一種動(dòng)態(tài)替換服務(wù)實(shí)現(xiàn)者的機(jī)制。

所以,Dubbo如此被廣泛接納的其中的 一個(gè)重要原因就是基于SPI實(shí)現(xiàn)的強(qiáng)大靈活的擴(kuò)展機(jī)制,開發(fā)者可自定義插件嵌入Dubbo,實(shí)現(xiàn)靈活的業(yè)務(wù)需求。

Java SPI

JDK為SPI的實(shí)現(xiàn)提供了工具類,即java.util.ServiceLoader,ServiceLoader中定義的SPI規(guī)范沒有什么特別之處,只需要有一個(gè)提供者配置文件(provider-configuration file),該文件需要在resource目錄META-INF/services下,文件名就是服務(wù)接口的全限定名。

  1. 文件內(nèi)容是提供者Class的全限定名列表,顯然提供者Class都應(yīng)該實(shí)現(xiàn)服務(wù)接口;
  2. 文件必須使用UTF-8編碼;

示例

public interface Cmand {    public void execute();}public class ShutdownCommand implements Cmand {    public void execute() {        System.out.println("shutdown....");    }}public class StartCommand implements Cmand {    public void execute() {        System.out.println("start....");    }}public class SPIMain {    public static void main(String[] args) {        ServiceLoader<Cmand> loader = ServiceLoader.load(Cmand.class);        System.out.println(loader);        for (Cmand Cmand : loader) {            Cmand.execute();        }    }}

缺點(diǎn)

  • 雖然ServiceLoader也算是使用的延遲加載,但是只能通過遍歷獲取,也就是遍歷的時(shí)候,接口的實(shí)現(xiàn)類會(huì)全部加載并實(shí)例化一遍。如果你并不想用某些實(shí)現(xiàn)類,它也被加載并實(shí)例化了,這就造成了浪費(fèi)。
  • 獲取某個(gè)實(shí)現(xiàn)類的方式不夠靈活,只能通過Iterator形式獲取,不能根據(jù)某個(gè)參數(shù)來(lái)獲取對(duì)應(yīng)的實(shí)現(xiàn)類。

Dubbo SPI

Dubbo對(duì)JDK SPI進(jìn)行了擴(kuò)展,對(duì)服務(wù)提供者配置文件中的內(nèi)容進(jìn)行了改造,由原來(lái)的提供者類的全限定名列表改成了KV形式的列表,這也導(dǎo)致了Dubbo中無(wú)法直接使用JDK ServiceLoader,所以,與之對(duì)應(yīng)的,在Dubbo中有ExtensionLoader。

ExtensionLoader是擴(kuò)展點(diǎn)載入器,用于載入Dubbo中的各種可配置組件,比如:負(fù)載均衡策略(LoadBalance)、攔截器(Filter)、集群方式(Cluster)等。

總之,Dubbo為了應(yīng)對(duì)各種場(chǎng)景,它的所有內(nèi)部組件都是通過這種SPI的方式來(lái)管理的,這也是為什么Dubbo需要將服務(wù)提供者配置文件設(shè)計(jì)成KV鍵值對(duì)形式,這個(gè)K就是我們?cè)贒ubbo配置文件或注解中用到的K,Dubbo直接通過服務(wù)接口(上面提到的ProxyFactory、LoadBalance、Protocol、Filter等)和配置的K從ExtensionLoader拿到服務(wù)提供的實(shí)現(xiàn)類。

SPI 全稱為 Service Provider Interface,是一種服務(wù)發(fā)現(xiàn)機(jī)制。SPI 的本質(zhì)是將接口實(shí)現(xiàn)類的全限定名配置在文件中,并由服務(wù)加載器讀取配置文件,加載實(shí)現(xiàn)類。這樣可以在運(yùn)行時(shí),動(dòng)態(tài)為接口替換實(shí)現(xiàn)類。正因此特性,我們可以很容易的通過 SPI 機(jī)制為我們的程序提供拓展功能。SPI 機(jī)制在第三方框架中也有所應(yīng)用,比如 Dubbo 就是通過 SPI 機(jī)制加載所有的組件。不過,Dubbo 并未使用 Java 原生的 SPI 機(jī)制,而是對(duì)其進(jìn)行了增強(qiáng),使其能夠更好的滿足需求。在 Dubbo 中,SPI 是一個(gè)非常重要的模塊?;?SPI,我們可以很容易的對(duì) Dubbo 進(jìn)行拓展。如果大家想要學(xué)習(xí) Dubbo 的源碼,SPI 機(jī)制務(wù)必弄懂。

擴(kuò)展功能介紹

Dubbo對(duì)SPI的擴(kuò)展是 通過ExtensionLoader來(lái)實(shí)現(xiàn)的。

Dubbo通過SPI注解定義了可擴(kuò)展的接口,如LoadBalance、Filter、Transporter等。每個(gè)類型的擴(kuò)展對(duì)應(yīng)一個(gè)ExtensionLoader。SPI的value參數(shù)決定了默認(rèn)的擴(kuò)展實(shí)現(xiàn)。

查看ExtensionLoader的源碼,可以看到Dubbo對(duì)JDK SPI 做了三個(gè)方面的擴(kuò)展:

  • 方便獲取擴(kuò)展實(shí)現(xiàn):JDK SPI僅僅通過接口類名獲取所有實(shí)現(xiàn),而ExtensionLoader則通過接口類名和key值獲取一個(gè)實(shí)現(xiàn)
  • IOC依賴注入功能:Adaptive實(shí)現(xiàn),就是生成一個(gè)代理類,這樣就可以根據(jù)實(shí)際調(diào)用時(shí)的一些參數(shù)動(dòng)態(tài)決定要調(diào)用的類了。

    • 舉例來(lái)說(shuō):接口A,實(shí)現(xiàn)者A1、A2。接口B,實(shí)現(xiàn)者B1、B2。

      現(xiàn)在實(shí)現(xiàn)者A1含有setB()方法,會(huì)自動(dòng)注入一個(gè)接口B的實(shí)現(xiàn)者,此時(shí)注入B1還是B2呢?都不是,而是注入一個(gè)動(dòng)態(tài)生成的接口B的實(shí)現(xiàn)者 B$Adpative,該實(shí)現(xiàn)者能夠根據(jù)參數(shù)的不同,自動(dòng)引用B1或者B2來(lái)完成相應(yīng)的功能;

  • 采用裝飾器模式進(jìn)行功能增強(qiáng),自動(dòng)包裝實(shí)現(xiàn),這種實(shí)現(xiàn)的類一般是自動(dòng)激活的,常用于包裝類,比如:Protocol的兩個(gè)實(shí)現(xiàn)類:ProtocolFilterWrapper、ProtocolListenerWrapper。

    • 還是第2個(gè)的例子,接口A的另一個(gè)實(shí)現(xiàn)者AWrapper1。大體內(nèi)容如下:

      private A a;AWrapper1(A a){   this.a=a;}

      因此,當(dāng)在獲取某一個(gè)接口A的實(shí)現(xiàn)者A1的時(shí)候,已經(jīng)自動(dòng)被AWrapper1包裝了。

擴(kuò)展源碼分析

通過ExtensionLoader加載一個(gè)實(shí)現(xiàn)類的流程,大致如下:

  • 獲取ExtensionLoader

    • 在Dubbo中每一個(gè)擴(kuò)展接口都對(duì)應(yīng)有一個(gè)ExtensionLoader
  • 加載所有擴(kuò)展類的具體實(shí)現(xiàn)類

    • dubbo會(huì)掃描META-INF/dubbo/internal、META-INF/dubbo、META-INF/services三個(gè)目錄下的配置文件
    • 然后加載配置文件中的擴(kuò)展實(shí)現(xiàn)類,放到一個(gè)map中,鍵就是SPI的key,值為擴(kuò)展實(shí)現(xiàn)類的class
  • 通過SPI的key獲取擴(kuò)展實(shí)現(xiàn)類
  • 實(shí)例化擴(kuò)展實(shí)現(xiàn)類
  • 對(duì)擴(kuò)展實(shí)現(xiàn)類進(jìn)行依賴注入
  • 如果有裝飾類型,則包上一層裝飾類型
  • 返回?cái)U(kuò)展類實(shí)例

PS:本人解析源碼不喜歡貼一大段代碼,因?yàn)橛袝r(shí)候貼一大段代碼出來(lái),讀者未必能看懂代碼到底在做什么。
一般我會(huì)把主流程寫出來(lái),細(xì)節(jié)讀者可自己深究。

參考

SPI示例及概念

Dubbo SPI原理流程

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java SPI 與 Dubbo SPI
聊聊 Java SPI 機(jī)制
dubbo學(xué)習(xí)思路梳理
SpringBoot 插件化開發(fā)模式,強(qiáng)烈推薦!
高級(jí)開發(fā)必須理解的Java中SPI機(jī)制
Dubbo的spi機(jī)制分析和實(shí)戰(zhàn)案例
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服