亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

java動(dòng)態(tài)代理及RPC框架介紹

2shou / 1110人閱讀

摘要:這種語(yǔ)法,在中被稱為動(dòng)態(tài)代理。在動(dòng)態(tài)代理機(jī)制中,這個(gè)角色只能是接口。動(dòng)態(tài)代理就是實(shí)現(xiàn)的技術(shù)之一。

所謂動(dòng)態(tài)代理,指的是語(yǔ)言提供的一種語(yǔ)法,能夠?qū)?duì)對(duì)象中不同方法的調(diào)用重定向到一個(gè)統(tǒng)一的處理函數(shù)中來(lái)。
python重寫__getattr__函數(shù)能夠做到這一點(diǎn),就連世界上最好的語(yǔ)言也提供稱為魔術(shù)方法的__call
這種語(yǔ)法除了能更好的實(shí)現(xiàn)動(dòng)態(tài)代理外,還是RPC框架實(shí)現(xiàn)原理的一部分。

動(dòng)態(tài)代理是什么

動(dòng)態(tài)代理提供一種抽象,能夠?qū)?duì)象中不同方法的調(diào)用重定向到一個(gè)統(tǒng)一的處理函數(shù),做自定義的邏輯處理。
但是對(duì)于調(diào)用者,對(duì)此毫無(wú)察覺,就好像調(diào)用的方法是用傳統(tǒng)方式實(shí)現(xiàn)的一般。

這種語(yǔ)法,在java中被稱為動(dòng)態(tài)代理。之所以叫做動(dòng)態(tài)代理,是因?yàn)樗鼙苊鈧鹘y(tǒng)代理模式實(shí)現(xiàn)中人工一個(gè)一個(gè)的將java函數(shù)轉(zhuǎn)發(fā)過(guò)去,
而是能夠讓代碼自動(dòng)做到這一點(diǎn),這樣代理類的代碼是和業(yè)務(wù)無(wú)關(guān)的,不會(huì)因?yàn)闃I(yè)務(wù)類的方法增多而逐漸龐大。
使代碼更易維護(hù)更易修改,實(shí)現(xiàn)自動(dòng)化搬磚。

實(shí)際上,被代理的類不一定位于本機(jī)類,動(dòng)態(tài)代理語(yǔ)法提供了一種抽象方式,被代理的類也可以位于遠(yuǎn)程主機(jī)上,這也是RPC框架實(shí)現(xiàn)原理的一部分。

理解了動(dòng)態(tài)代理的概念后不難發(fā)現(xiàn),動(dòng)態(tài)代理概念上有著這么幾個(gè)部分:

給調(diào)用者使用的代理類。在java中,我們發(fā)現(xiàn)動(dòng)態(tài)代理提供的抽象天然契合面向接口編程,因此它也有可能是接口。

一個(gè)統(tǒng)一的處理函數(shù),收集不同函數(shù)轉(zhuǎn)發(fā)過(guò)來(lái)的請(qǐng)求,可自定義處理邏輯集中處理。java中它可能會(huì)成為一個(gè)較獨(dú)立的部分,因此也可能是類。

java動(dòng)態(tài)代理機(jī)制

理解了概念,就不難理解java動(dòng)態(tài)代理的機(jī)制了。下面來(lái)看看java動(dòng)態(tài)代理機(jī)制如何代理一個(gè)本地對(duì)象。

代理接口

首先看第一個(gè)部分,給調(diào)用者使用的代理類。在java動(dòng)態(tài)代理機(jī)制中,這個(gè)角色只能是接口。我們定義一個(gè)整數(shù)運(yùn)算接口:

interface NumberOperationInterface {
    int add(int a, int b);
}
代理處理器

再看第二個(gè)角色,統(tǒng)一的處理函數(shù)。在java中它的確是類,通過(guò)實(shí)現(xiàn)InvocationHandler接口定義。

class NumberOperationImpProxyHandler implements InvocationHandler {

    private Object proxied;

    public RealObjectProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.printf("調(diào)用函數(shù)%s
", method.getName());
        return method.invoke(proxied, args);
    }

}

由于我們的例子是代理本地對(duì)象,那么處理函數(shù)是需要被代理對(duì)象的信息??梢钥吹?,我們從構(gòu)造函數(shù)中將被代理對(duì)象保存在該類中,即可從處理函數(shù)中訪問(wèn)到。

invoke函數(shù)中,對(duì)代理對(duì)象的所有方法的調(diào)用都被轉(zhuǎn)發(fā)至該函數(shù)處理。在這里可以靈活的自定義各種你能想到的邏輯。在上面的代碼中,我們使用反射調(diào)用被代理對(duì)象的同名方法實(shí)現(xiàn)。

被代理類

由于我們的示例是代理本地對(duì)象,因此還需要一個(gè)被代理對(duì)象的類:

class NumberOperationImp implements NumerOperationInterface {

    @Override
    public int add(int a, int b) {
        return a + b;
    }
}
創(chuàng)建代理對(duì)象

好了,各個(gè)組成部分都定義完成?,F(xiàn)在把它們組合起來(lái):

public NumerOperationInterface wrap(NumerOperationInterface proxied) {
    return (NumerOperationInterface) Proxy.newProxyInstance(
        NumerOperationInterface.class.getClassLoader(),
        new Class[]{NumerOperationInterface.class},
        new NumberOperationImpProxyHandler(proxied));
}

由于java提供的這個(gè)寫法實(shí)在是太啰嗦了,所以把它放入一個(gè)輔助函數(shù)中。

Proxy.newProxyInstance 方法能夠根據(jù)提供的接口和代理處理器創(chuàng)建代理對(duì)象。

java提供的寫法太啰嗦了,可以考慮使用Guake提供的輔助函數(shù)簡(jiǎn)化下代碼。如下:

public NumerOperationInterface wrap(NumerOperationInterface proxied) {
    return Reflection.newProxy(NumerOperationInterface.class, new NumberOperationImpProxyHandler(proxied));
}

好了,現(xiàn)在調(diào)用下試試:

NumerOperationInterface proxied = new NumberOperationImp();
real = wrap(proxied);
real.add(1, 2);
總結(jié)

動(dòng)態(tài)代理聽起來(lái)是代理模式的動(dòng)態(tài)實(shí)現(xiàn),可是結(jié)合上面的最終效果,不覺得這個(gè)叫做動(dòng)態(tài)裝飾器更合適嗎?

動(dòng)態(tài)代理的應(yīng)用

說(shuō)完了動(dòng)態(tài)代理的概念和實(shí)現(xiàn)機(jī)制,該看看使用動(dòng)態(tài)代理有哪些應(yīng)用。

應(yīng)用一:代理模式/裝飾器模式的動(dòng)態(tài)實(shí)現(xiàn)

這個(gè)應(yīng)用場(chǎng)景前面據(jù)已經(jīng)提到過(guò)。
代理模式和裝飾器模式是編程當(dāng)中很常用的技巧,用于提升代碼的靈活性和可擴(kuò)展性。
傳統(tǒng)代理模式的實(shí)現(xiàn)方式比較暴力直接,需要將所有被代理類的所有方法都寫一遍,并且一個(gè)個(gè)的手動(dòng)轉(zhuǎn)發(fā)過(guò)去。
在維護(hù)被代理類的同時(shí),作為java碼工還需要同時(shí)維護(hù)代理類的相關(guān)代碼,實(shí)在是累心。

通過(guò)使用動(dòng)態(tài)代理,動(dòng)態(tài)代理能夠自動(dòng)將代理類的相關(guān)方法轉(zhuǎn)發(fā)到被代理類,可以看到:

代理轉(zhuǎn)發(fā)的過(guò)程自動(dòng)化了,實(shí)現(xiàn)自動(dòng)化搬磚。

代理類的代碼邏輯和具體業(yè)務(wù)邏輯解耦,與業(yè)務(wù)無(wú)關(guān)。

應(yīng)用二:實(shí)現(xiàn)AOP

是的,利用動(dòng)態(tài)代理也能實(shí)現(xiàn)AOP。仔細(xì)推演一下不能得出這個(gè)結(jié)論。我們知道:

動(dòng)態(tài)代理提供了一種方式,能夠?qū)⒎稚⒌姆椒ㄕ{(diào)用轉(zhuǎn)發(fā)到一個(gè)統(tǒng)一的處理函數(shù)處理。

AOP的實(shí)現(xiàn)需要能夠提供這樣一種機(jī)制,即在執(zhí)行函數(shù)前和執(zhí)行函數(shù)后都能執(zhí)行自己定義的鉤子。

那么,首先使用動(dòng)態(tài)代理讓代理類忠實(shí)的代理被代理類,然后處理函數(shù)中插入我們的自定義的鉤子。
之后讓代理類替換被代理類需要使用的場(chǎng)景,這樣,相當(dāng)于對(duì)該類的所有方法定義了一個(gè)切面。

不過(guò),使用動(dòng)態(tài)代理實(shí)現(xiàn)AOP特別麻煩,啰嗦。這僅僅作為一個(gè)探討的思路,來(lái)說(shuō)明動(dòng)態(tài)代理這一通用概念可以實(shí)現(xiàn)很多特定技術(shù)。
實(shí)際使用中當(dāng)然使用spring提供的AOP更為方便。

應(yīng)用三:實(shí)現(xiàn)RPC

RPC即遠(yuǎn)程過(guò)程調(diào)用,在分布式的網(wǎng)站架構(gòu)中是一個(gè)非常重要的技術(shù),目前現(xiàn)在流行的SOA架構(gòu),微服務(wù)架構(gòu),它們的核心原理之一就是RPC調(diào)用。

從概念上來(lái)說(shuō),RPC的概念是非常簡(jiǎn)潔優(yōu)美的。RPC方法的調(diào)用和普通的方法并無(wú)二異,調(diào)用者不需要操心具體的實(shí)現(xiàn),這是抽象提供的威力。
實(shí)現(xiàn)上,它將函數(shù)調(diào)用方和函數(shù)的提供方分散在兩個(gè)不同的進(jìn)程上,中間使用網(wǎng)絡(luò)通信來(lái)進(jìn)行數(shù)據(jù)交互。

動(dòng)態(tài)代理就是實(shí)現(xiàn)RPC的技術(shù)之一。只要理解了動(dòng)態(tài)代理和RPC,我們很容易發(fā)現(xiàn)這樣一個(gè)事實(shí):
RPC調(diào)用其實(shí)是對(duì)遠(yuǎn)程另外一臺(tái)機(jī)器進(jìn)程上的對(duì)象的代理。

仔細(xì)思考RPC調(diào)用的數(shù)據(jù)流流向,就能梳理出這樣的思路:

調(diào)用方調(diào)用本地的RPC代理方法,將參數(shù)提供給該方法。

不同的RPC代理方法被轉(zhuǎn)發(fā)到一個(gè)統(tǒng)一的處理中心,該處理中心知道調(diào)用的是那個(gè)函數(shù),參數(shù)是什么。

該處理中心將調(diào)用的信息封裝打包,通過(guò)網(wǎng)絡(luò)發(fā)送給另外一個(gè)進(jìn)程。

另外一個(gè)進(jìn)程接受到調(diào)用進(jìn)程發(fā)送過(guò)來(lái)的數(shù)據(jù)包。

該進(jìn)程根據(jù)數(shù)據(jù)包中記錄的RPC調(diào)用信息,將調(diào)用分發(fā)給對(duì)應(yīng)的被代理對(duì)象的對(duì)應(yīng)方法去執(zhí)行。

返回的話思路類似。

顯而易見,第二步,需要使用動(dòng)態(tài)代理將分散的函數(shù)調(diào)用轉(zhuǎn)發(fā)到一個(gè)統(tǒng)一的處理中心;第五步,將統(tǒng)一收集來(lái)的調(diào)用信息分發(fā)給具體的函數(shù)執(zhí)行,顯然使用反射做到這一點(diǎn)。
有了這個(gè)思路,通過(guò)利用動(dòng)態(tài)代理,反射,和網(wǎng)絡(luò)編程技術(shù),實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的RPC框架也就不難了。
考慮到本文是介紹動(dòng)態(tài)代理的,關(guān)于RPC的細(xì)節(jié)實(shí)現(xiàn)有時(shí)間新開一篇博文分析。

最后

總得來(lái)說(shuō),通過(guò)一定的思考,個(gè)人覺得動(dòng)態(tài)代理的核心在于:將分散的對(duì)對(duì)象不同方法的調(diào)用轉(zhuǎn)發(fā)到一個(gè)同一的處理函數(shù)中來(lái)。

有了這個(gè)關(guān)鍵點(diǎn),很多其它技術(shù)的實(shí)現(xiàn)需要借助于動(dòng)態(tài)代理的這一個(gè)關(guān)鍵點(diǎn)實(shí)現(xiàn),也因此動(dòng)態(tài)代理也有著這么多的應(yīng)用。

注:該文于2018-03-30撰寫于我的github靜態(tài)頁(yè)博客,現(xiàn)同步到我的segmentfault來(lái)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/71426.html

相關(guān)文章

  • RPC框架原理從零實(shí)現(xiàn)系列博客(一):思路篇

    摘要:等之所以支持跨語(yǔ)言,是因?yàn)樗麄冏约憾x了一套結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)格式,如的,用于編解碼對(duì)象,作為各個(gè)語(yǔ)言通信的中間協(xié)議。 前段時(shí)間覺得自己一直用別人的框架,站在巨人的肩膀上,也該自己造造輪子了 一時(shí)興起 就著手寫起了RPC框架 這里寫了系列博客拿給大家分享下 這篇是開篇的思路篇 項(xiàng)目最終的代碼放在了我的github上https://github.com/wephone/Me... 歡迎sta...

    tracy 評(píng)論0 收藏0
  • RPC框架原理從零實(shí)現(xiàn)系列博客(二):11個(gè)類實(shí)現(xiàn)簡(jiǎn)單RPC框架

    摘要:項(xiàng)目版本源碼在上一博文中跟大家講了的實(shí)現(xiàn)思路思路畢竟只是思路那么這篇就帶著源碼給大家講解下實(shí)現(xiàn)過(guò)程中的各個(gè)具體問(wèn)題讀懂本篇需要的基本知識(shí)若尚未清晰請(qǐng)自行了解后再閱讀本文動(dòng)態(tài)代理框架的基本使用的基本配置最終項(xiàng)目的使用如下調(diào)用端代碼及配置測(cè)試類 項(xiàng)目1.0版本源碼 https://github.com/wephone/Me... 在上一博文中 跟大家講了RPC的實(shí)現(xiàn)思路 思路畢竟只是思路...

    you_De 評(píng)論0 收藏0
  • 手把手教你基于Netty實(shí)現(xiàn)一個(gè)基礎(chǔ)的RPC框架(通俗易懂)

    摘要:是一個(gè)分布式服務(wù)框架,以及治理方案。手寫注意要點(diǎn)手寫注意要點(diǎn)基于上文中對(duì)于協(xié)議的理解,如果我們自己去實(shí)現(xiàn),需要考慮哪些技術(shù)呢其實(shí)基于圖的整個(gè)流程應(yīng)該有一個(gè)大概的理解?;谑謱憣?shí)現(xiàn)基于手寫實(shí)現(xiàn)理解了協(xié)議后,我們基于來(lái)實(shí)現(xiàn)一個(gè)通信框架。閱讀這篇文章之前,建議先閱讀和這篇文章關(guān)聯(lián)的內(nèi)容。[1]詳細(xì)剖析分布式微服務(wù)架構(gòu)下網(wǎng)絡(luò)通信的底層實(shí)現(xiàn)原理(圖解)[2][年薪60W的技巧]工作了5年,你真的理解N...

    番茄西紅柿 評(píng)論0 收藏2637
  • Java面試 32個(gè)核心必考點(diǎn)完全解析

    摘要:如問(wèn)到是否使用某框架,實(shí)際是是問(wèn)該框架的使用場(chǎng)景,有什么特點(diǎn),和同類可框架對(duì)比一系列的問(wèn)題。這兩個(gè)方向的區(qū)分點(diǎn)在于工作方向的側(cè)重點(diǎn)不同。 [TOC] 這是一份來(lái)自嗶哩嗶哩的Java面試Java面試 32個(gè)核心必考點(diǎn)完全解析(完) 課程預(yù)習(xí) 1.1 課程內(nèi)容分為三個(gè)模塊 基礎(chǔ)模塊: 技術(shù)崗位與面試 計(jì)算機(jī)基礎(chǔ) JVM原理 多線程 設(shè)計(jì)模式 數(shù)據(jù)結(jié)構(gòu)與算法 應(yīng)用模塊: 常用工具集 ...

    JiaXinYi 評(píng)論0 收藏0
  • java動(dòng)態(tài)代理的理解

    摘要:動(dòng)態(tài)代理能干嘛提供了另外一種實(shí)現(xiàn)接口的方式,不用也能實(shí)現(xiàn)接口。有了動(dòng)態(tài)代理,中的網(wǎng)絡(luò)交互部分可以完全寫在框架中,對(duì)用戶來(lái)說(shuō)編程更加方便。 靜態(tài)代理 public class TargetClass{ void method1() } public class ProxyClass{ private TargetClass target; public...

    IamDLY 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<