Dubbo Adaptive機(jī)制1 - 動(dòng)態(tài)擴(kuò)展加載优构、$Adaptive類

Dubbo的Adaptive機(jī)制是什么?

在回答這個(gè)問題之前雁竞,我們先說說擴(kuò)展和Dubbo的SPI機(jī)制钦椭。

評(píng)價(jià)一個(gè)軟件擴(kuò)展性好不好,說的是軟件本身有沒有預(yù)留足夠的擴(kuò)展點(diǎn)碑诉,讓用戶去自定義軟件的功能彪腔,讓軟件調(diào)用你的代碼,運(yùn)行你的代碼邏輯进栽。比如在Web開發(fā)中德挣,常常會(huì)自定義一些Filter,在一個(gè)請(qǐng)求的前后做一些額外的處理快毛。用Java的語言來講格嗅,擴(kuò)展點(diǎn)就是接口(Interface)番挺,擴(kuò)展就是接口實(shí)現(xiàn)(implement)。

那Dubbo的SPI是什么屯掖?Dubbo的SPI機(jī)制玄柏,就是擴(kuò)展點(diǎn)加載機(jī)制。Dubbo允許用戶在配置文件中配置擴(kuò)展贴铜,形式為:key=value粪摘,key為擴(kuò)展的名稱,value是擴(kuò)展類的全限定名阀湿。例如赶熟,一個(gè)擴(kuò)展點(diǎn)是Animal,有3個(gè)實(shí)現(xiàn)陷嘴,分別是Dog映砖、Cat、Tiger灾挨,在配置文件中做如下配置:
dog=com.xxx.Dog
然后在代碼中調(diào)用:
Animal dog = ExtensionLoader.getExtensionLoader(Animal.class).getExtension("dog");
即可獲取到Dog的實(shí)例邑退。但是擴(kuò)展名(dog)是寫死的,如果我想換成cat劳澄,需要寫成:
Animal cat = ExtensionLoader.getExtensionLoader(Animal.class).getExtension("cat");
寫死名稱很不靈活地技,在有些場(chǎng)景下,需要?jiǎng)討B(tài)的獲取擴(kuò)展秒拔,有時(shí)想要cat實(shí)例莫矗,有時(shí)需要dog實(shí)例。那怎么做呢砂缩,很簡(jiǎn)單只要擴(kuò)展名是一個(gè)變量作谚,就可以實(shí)現(xiàn)動(dòng)態(tài)獲取擴(kuò)展了:
Animal animal = ExtensionLoader.getExtensionLoader(Animal.class).getExtension(animal);

Dubbo的Adaptive機(jī)制,正是利用URL這個(gè)參數(shù)庵芭,在運(yùn)行過程中動(dòng)態(tài)的加載擴(kuò)展妹懒。具體為,@Adaptive注解定義從URL取哪個(gè)key双吆,對(duì)應(yīng)的value就是擴(kuò)展的名稱:

URL url = arg.getUrl();
String extName = url.getParameter( "animal_type", "cat");
Animal extension = ExtensionLoader
                      .getExtensionLoader( Animal.class )
                      .getExtension( extName );

其中眨唬,animal_type是在注解@Adaptive中定義的,cat是默認(rèn)的擴(kuò)展名

Dubbo會(huì)為方法上標(biāo)注有@Adaptive的擴(kuò)展點(diǎn)好乐,自動(dòng)生成一個(gè)$Adaptive后綴的包裝類匾竿,包裝類中的邏輯,就是上述所說的從URL中獲取擴(kuò)展名曹宴,再獲取擴(kuò)展的過程搂橙。

最終,獲取adaptive擴(kuò)展的代碼為:
Animal animal = ExtensionLoader.getExtensionLoader(Animal.class).getAdaptiveExtension();

下面具體看下Dubbo為我們生成的包裝類的代碼長(zhǎng)什么樣?
以ProxyFactory為例区转,生成的ProxyFactory$Adaptive類的代碼如下:

@SPI("javassist")
public interface ProxyFactory {
    
    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker) throws RpcException;
    
    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException;
    
    @Adaptive({Constants.PROXY_KEY})
    <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;

}
public class ProxyFactory$Adaptive implements com.alibaba.dubbo.rpc.ProxyFactory {

    public java.lang.Object getProxy( com.alibaba.dubbo.rpc.Invoker arg0 ) throws com.alibaba.dubbo.rpc.RpcException
    {
        if ( arg0 == null )
            throw new IllegalArgumentException( "com.alibaba.dubbo.rpc.Invoker argument == null" );

        if ( arg0.getUrl() == null )
            throw new IllegalArgumentException( "com.alibaba.dubbo.rpc.Invoker argument getUrl() == null" );

        com.alibaba.dubbo.common.URL url    = arg0.getUrl();
        String extName = url.getParameter( "proxy", "javassist" );
        if ( extName == null )
            throw new IllegalStateException( "Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])" );

        com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader
                .getExtensionLoader( com.alibaba.dubbo.rpc.ProxyFactory.class )
                .getExtension( extName );

        return (extension.getProxy( arg0 ) );
    }

    // 省略其他2個(gè)方法
}

在這里打個(gè)斷點(diǎn)苔巨,就能看到動(dòng)態(tài)拼接的adaptive包裝類的代碼:com.alibaba.dubbo.common.extension.ExtensionLoader#createAdaptiveExtensionClass

private Class<?> createAdaptiveExtensionClass() {
        String code = createAdaptiveExtensionClassCode();
        ClassLoader classLoader = findClassLoader();
        com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
        return compiler.compile(code, classLoader);
    }

下一篇,我們將從源碼的角度废离,分析Adaptive機(jī)制侄泽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蜻韭,隨后出現(xiàn)的幾起案子悼尾,更是在濱河造成了極大的恐慌,老刑警劉巖肖方,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闺魏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡俯画,警方通過查閱死者的電腦和手機(jī)析桥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艰垂,“玉大人泡仗,你說我怎么就攤上這事〔略鳎” “怎么了娩怎?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)胰柑。 經(jīng)常有香客問我截亦,道長(zhǎng),這世上最難降的妖魔是什么柬讨? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任魁巩,我火速辦了婚禮,結(jié)果婚禮上姐浮,老公的妹妹穿的比我還像新娘。我一直安慰自己葬馋,他們只是感情好卖鲤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著畴嘶,像睡著了一般蛋逾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窗悯,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天区匣,我揣著相機(jī)與錄音,去河邊找鬼蒋院。 笑死亏钩,一個(gè)胖子當(dāng)著我的面吹牛莲绰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姑丑,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蛤签,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了栅哀?” 一聲冷哼從身側(cè)響起震肮,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎留拾,沒想到半個(gè)月后戳晌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痴柔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年沦偎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竞帽。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扛施,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出屹篓,到底是詐尸還是另有隱情疙渣,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布堆巧,位于F島的核電站妄荔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谍肤。R本人自食惡果不足惜啦租,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荒揣。 院中可真熱鬧篷角,春花似錦、人聲如沸系任。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俩滥。三九已至嘉蕾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間霜旧,已是汗流浹背错忱。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人以清。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓儿普,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親玖媚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子箕肃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345