Dubbo消費端服務(wù)代理類

引言

我們知道Dubbo消費端引用服務(wù)的時候是根據(jù)本地接口為我們生成代理類,對消費端而言不需要關(guān)心具體的實現(xiàn),代理類幫我們處理底層通信的問題。

        ReferenceConfig<IUserService> reference = newReferenceConfig<IUserService>(); 
        reference.setApplication(application);
        reference.setRegistry(registry); // 多個注冊中心可以用setRegistries()
        reference.setInterface(IUserService.class);
        reference.setVersion("1.0.0");

        //此時的userService只是IUserService的一個代理類
        IUserService userService = reference.get(); 

代理類反編譯

public class Proxy0 extends Proxy implements DC {
    public Object newInstance(InvocationHandler var1) {
        return new proxy0(var1);
    }

    public Proxy0() {
    }
}
package com.alibaba.dubbo.common.bytecode;

import com.alibaba.dubbo.common.bytecode.ClassGenerator.DC;
import com.alibaba.dubbo.demo.service.IUserService;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;

public class proxy0 implements DC, IUserService, EchoService {
    public static Method[] methods;
    private InvocationHandler handler;

    public List findAllUserList() {
        Object[] var1 = new Object[0];
        Object var2 = this.handler.invoke(this, methods[0], var1);
        return (List)var2;
    }

    public String findPasswd(String var1) {
        Object[] var2 = new Object[]{var1};
        Object var3 = this.handler.invoke(this, methods[1], var2);
        return (String)var3;
    }

    public void updateUserById(Integer var1) {
        Object[] var2 = new Object[]{var1};
        this.handler.invoke(this, methods[2], var2);
    }

    public Object $echo(Object var1) {
        Object[] var2 = new Object[]{var1};
        Object var3 = this.handler.invoke(this, methods[3], var2);
        return (Object)var3;
    }

    public proxy0() {
    }

    public proxy0(InvocationHandler var1) {
        this.handler = var1;
    }
}

從代碼中可知,具體的方法都是由handler.invoke()來執(zhí)行的,而且該代理類實現(xiàn)了IUserService接口.我們來看一下JavassistProxyFactory:

public class JavassistProxyFactory extends AbstractProxyFactory {

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // TODO Wrapper類不能正確處理帶$的類名
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName, 
                                      Class<?>[] parameterTypes, 
                                      Object[] arguments) throws Throwable {
                return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
            }
        };
    }
}

從代碼中可知,newInstance()方法里包裝了一個InvokerInvocationHandler()對象仿荆。

public class InvokerInvocationHandler implements InvocationHandler {

    private final Invoker<?> invoker;
    
    public InvokerInvocationHandler(Invoker<?> handler){
        this.invoker = handler;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (method.getDeclaringClass() == Object.class) {
            return method.invoke(invoker, args);
        }
        if ("toString".equals(methodName) && parameterTypes.length == 0) {
            return invoker.toString();
        }
        if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
            return invoker.hashCode();
        }
        if ("equals".equals(methodName) && parameterTypes.length == 1) {
            return invoker.equals(args[0]);
        }
        return invoker.invoke(new RpcInvocation(method, args)).recreate();
    }

}

具體的邏輯最終交給了Invoker來執(zhí)行厅贪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市更卒,隨后出現(xiàn)的幾起案子拉鹃,更是在濱河造成了極大的恐慌窘疮,老刑警劉巖骑素,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炫乓,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機末捣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門侠姑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人箩做,你說我怎么就攤上這事结借。” “怎么了卒茬?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咖熟。 經(jīng)常有香客問我圃酵,道長,這世上最難降的妖魔是什么馍管? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任郭赐,我火速辦了婚禮,結(jié)果婚禮上确沸,老公的妹妹穿的比我還像新娘捌锭。我一直安慰自己,他們只是感情好罗捎,可當(dāng)我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布观谦。 她就那樣靜靜地躺著,像睡著了一般桨菜。 火紅的嫁衣襯著肌膚如雪豁状。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天倒得,我揣著相機與錄音泻红,去河邊找鬼。 笑死霞掺,一個胖子當(dāng)著我的面吹牛谊路,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播菩彬,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缠劝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了骗灶?” 一聲冷哼從身側(cè)響起剩彬,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎矿卑,沒想到半個月后喉恋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年轻黑,在試婚紗的時候發(fā)現(xiàn)自己被綠了糊肤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡氓鄙,死狀恐怖馆揉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抖拦,我是刑警寧澤升酣,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站态罪,受9級特大地震影響噩茄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜复颈,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一绩聘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧耗啦,春花似錦凿菩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至似将,卻和暖如春会喝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玩郊。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工肢执, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人译红。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓预茄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侦厚。 傳聞我的和親對象是個殘疾皇子耻陕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,652評論 2 354

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