dubbo 的 spi 思想是什么血淌?

面試題

dubbo 的 spi 思想是什么?

面試官心理分析

繼續(xù)深入問唄财剖,前面一些基礎(chǔ)性的東西問完了悠夯,確定你應(yīng)該都 ok,了解 dubbo 的一些基本東西躺坟,那么問個(gè)稍微難一點(diǎn)點(diǎn)的問題沦补,就是 spi,先問問你 spi 是啥咪橙?然后問問你 dubbo 的 spi 是怎么實(shí)現(xiàn)的夕膀?

其實(shí)就是看看你對(duì) dubbo 的掌握如何虚倒。

面試題剖析

spi 是啥?

spi产舞,簡(jiǎn)單來說魂奥,就是 service provider interface,說白了是什么意思呢易猫,比如你有個(gè)接口耻煤,現(xiàn)在這個(gè)接口有 3 個(gè)實(shí)現(xiàn)類,那么在系統(tǒng)運(yùn)行的時(shí)候?qū)@個(gè)接口到底選擇哪個(gè)實(shí)現(xiàn)類呢准颓?這就需要 spi 了哈蝇,需要根據(jù)指定的配置或者是默認(rèn)的配置,去找到對(duì)應(yīng)的實(shí)現(xiàn)類加載進(jìn)來攘已,然后用這個(gè)實(shí)現(xiàn)類的實(shí)例對(duì)象炮赦。

舉個(gè)栗子。

你有一個(gè)接口A样勃。A1/A2/A3 分別是接口A的不同實(shí)現(xiàn)眼五。你通過配置 接口A=實(shí)現(xiàn)A2,那么在系統(tǒng)實(shí)際運(yùn)行的時(shí)候彤灶,會(huì)加載你的配置看幼,用實(shí)現(xiàn)A2實(shí)例化一個(gè)對(duì)象來提供服務(wù)。

spi 機(jī)制一般用在哪兒幌陕?插件擴(kuò)展的場(chǎng)景诵姜,比如說你開發(fā)了一個(gè)給別人使用的開源框架,如果你想讓別人自己寫個(gè)插件搏熄,插到你的開源框架里面棚唆,從而擴(kuò)展某個(gè)功能,這個(gè)時(shí)候 spi 思想就用上了心例。

Java spi 思想的體現(xiàn)

spi 經(jīng)典的思想體現(xiàn)宵凌,大家平時(shí)都在用,比如說 jdbc止后。

Java 定義了一套 jdbc 的接口瞎惫,但是 Java 并沒有提供 jdbc 的實(shí)現(xiàn)類。

但是實(shí)際上項(xiàng)目跑的時(shí)候译株,要使用 jdbc 接口的哪些實(shí)現(xiàn)類呢瓜喇?一般來說,我們要根據(jù)自己使用的數(shù)據(jù)庫歉糜,比如 mysql乘寒,你就將 mysql-jdbc-connector.jar 引入進(jìn)來;oracle匪补,你就將 oracle-jdbc-connector.jar 引入進(jìn)來伞辛。

在系統(tǒng)跑的時(shí)候烂翰,碰到你使用 jdbc 的接口,他會(huì)在底層使用你引入的那個(gè) jar 中提供的實(shí)現(xiàn)類蚤氏。

dubbo 的 spi 思想

dubbo 也用了 spi 思想刽酱,不過沒有用 jdk 的 spi 機(jī)制,是自己實(shí)現(xiàn)的一套 spi 機(jī)制瞧捌。

Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

Protocol 接口棵里,在系統(tǒng)運(yùn)行的時(shí)候,姐呐,dubbo 會(huì)判斷一下應(yīng)該選用這個(gè) Protocol 接口的哪個(gè)實(shí)現(xiàn)類來實(shí)例化對(duì)象來使用殿怜。

它會(huì)去找一個(gè)你配置的 Protocol,將你配置的 Protocol 實(shí)現(xiàn)類曙砂,加載到 jvm 中來头谜,然后實(shí)例化對(duì)象,就用你的那個(gè) Protocol 實(shí)現(xiàn)類就可以了

上面那行代碼就是 dubbo 里大量使用的鸠澈,就是對(duì)很多組件柱告,都是保留一個(gè)接口和多個(gè)實(shí)現(xiàn),然后在系統(tǒng)運(yùn)行的時(shí)候動(dòng)態(tài)根據(jù)配置去找到對(duì)應(yīng)的實(shí)現(xiàn)類笑陈。如果你沒配置际度,那就走默認(rèn)的實(shí)現(xiàn)好了,沒問題涵妥。

@SPI("dubbo")  
public interface Protocol {  
      
    int getDefaultPort();  
  
    @Adaptive  
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;  
  
    @Adaptive  
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;  

    void destroy();  
  
}  

在 dubbo 自己的 jar 里乖菱,在/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件中:

dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol

所以說,這就看到了 dubbo 的 spi 機(jī)制默認(rèn)是怎么玩兒的了蓬网,其實(shí)就是 Protocol 接口窒所,@SPI(“dubbo”) 說的是,通過 SPI 機(jī)制來提供實(shí)現(xiàn)類帆锋,實(shí)現(xiàn)類是通過 dubbo 作為默認(rèn) key 去配置文件里找到的吵取,配置文件名稱與接口全限定名一樣的,通過 dubbo 作為 key 可以找到默認(rèn)的實(shí)現(xiàn)類就是 com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol锯厢。

如果想要?jiǎng)討B(tài)替換掉默認(rèn)的實(shí)現(xiàn)類皮官,需要使用 @Adaptive 接口,Protocol 接口中哲鸳,有兩個(gè)方法加了 @Adaptive 注解臣疑,就是說那倆接口會(huì)被代理實(shí)現(xiàn)。

啥意思呢徙菠?

比如這個(gè) Protocol 接口搞了倆 @Adaptive 注解標(biāo)注了方法,在運(yùn)行的時(shí)候會(huì)針對(duì) Protocol 生成代理類郁岩,這個(gè)代理類的那倆方法里面會(huì)有代理代碼婿奔,代理代碼會(huì)在運(yùn)行的時(shí)候動(dòng)態(tài)根據(jù) url 中的 protocol 來獲取那個(gè) key缺狠,默認(rèn)是 dubbo,你也可以自己指定萍摊,你如果指定了別的 key挤茄,那么就會(huì)獲取別的實(shí)現(xiàn)類的實(shí)例了。

如何自己擴(kuò)展 dubbo 中的組件

下面來說說怎么來自己擴(kuò)展 dubbo 中的組件冰木。

自己寫個(gè)工程穷劈,要是那種可以打成 jar 包的,里面的 src/main/resources 目錄下踊沸,搞一個(gè) META-INF/services歇终,里面放個(gè)文件叫:com.alibaba.dubbo.rpc.Protocol,文件里搞一個(gè)my=com.bingo.MyProtocol逼龟。自己把 jar 弄到 nexus 私服里去评凝。

然后自己搞一個(gè) dubbo provider 工程,在這個(gè)工程里面依賴你自己搞的那個(gè) jar腺律,然后在 spring 配置文件里給個(gè)配置:

<dubbo:protocol name=”my” port=”20000” />

provider 啟動(dòng)的時(shí)候奕短,就會(huì)加載到我們 jar 包里的my=com.bingo.MyProtocol 這行配置里,接著會(huì)根據(jù)你的配置使用你定義好的 MyProtocol 了匀钧,這個(gè)就是簡(jiǎn)單說明一下翎碑,你通過上述方式,可以替換掉大量的 dubbo 內(nèi)部的組件之斯,就是扔個(gè)你自己的 jar 包杈女,然后配置一下即可。

dubbo-spi

dubbo 里面提供了大量的類似上面的擴(kuò)展點(diǎn)吊圾,就是說达椰,你如果要擴(kuò)展一個(gè)東西,只要自己寫個(gè) jar项乒,讓你的 consumer 或者是 provider 工程啰劲,依賴你的那個(gè) jar,在你的 jar 里指定目錄下配置好接口名稱對(duì)應(yīng)的文件檀何,里面通過 key=實(shí)現(xiàn)類蝇裤。

然后對(duì)對(duì)應(yīng)的組件,用類似 <dubbo:protocol> 用你的那個(gè) key 對(duì)應(yīng)的實(shí)現(xiàn)類來實(shí)現(xiàn)某個(gè)接口频鉴,你可以自己去擴(kuò)展 dubbo 的各種功能栓辜,提供你自己的實(shí)現(xiàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末垛孔,一起剝皮案震驚了整個(gè)濱河市藕甩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌周荐,老刑警劉巖狭莱,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僵娃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡腋妙,警方通過查閱死者的電腦和手機(jī)默怨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骤素,“玉大人匙睹,你說我怎么就攤上這事〖弥瘢” “怎么了痕檬?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)规辱。 經(jīng)常有香客問我谆棺,道長(zhǎng),這世上最難降的妖魔是什么罕袋? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任改淑,我火速辦了婚禮,結(jié)果婚禮上浴讯,老公的妹妹穿的比我還像新娘朵夏。我一直安慰自己,他們只是感情好榆纽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布仰猖。 她就那樣靜靜地躺著,像睡著了一般奈籽。 火紅的嫁衣襯著肌膚如雪饥侵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天衣屏,我揣著相機(jī)與錄音躏升,去河邊找鬼。 笑死狼忱,一個(gè)胖子當(dāng)著我的面吹牛膨疏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钻弄,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼佃却,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了窘俺?” 一聲冷哼從身側(cè)響起饲帅,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后洒闸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體染坯,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡均芽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年丘逸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掀宋。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡深纲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出劲妙,到底是詐尸還是另有隱情湃鹊,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布镣奋,位于F島的核電站币呵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏侨颈。R本人自食惡果不足惜余赢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哈垢。 院中可真熱鬧妻柒,春花似錦、人聲如沸耘分。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽求泰。三九已至央渣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渴频,已是汗流浹背芽丹。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枉氮,地道東北人志衍。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像聊替,于是被迫代替她去往敵國和親楼肪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容