<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

    java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理在工作中用代理的地方非常多,但一直還沒(méi)仔細(xì)來(lái)看代理的原理,今天被同事提到,所以自己開(kāi)始仔細(xì)研究了一下這兩者代理都做了些什么工作,并通過(guò)編寫(xiě)測(cè)試用例的方式來(lái)對(duì)兩種代理原理作理解。
    在自行看代碼之前,初步問(wèn)了一下朋友,大概解釋這兩者區(qū)別是,java動(dòng)態(tài)代理是利用反射機(jī)制生成一個(gè)實(shí)現(xiàn)代理接口的匿名類(lèi),在調(diào)用具體方法前調(diào)用InvokeHandler來(lái)處理。而cglib動(dòng)態(tài)代理是利用asm開(kāi)源包,對(duì)代理對(duì)象類(lèi)的class文件加載進(jìn)來(lái),通過(guò)修改其字節(jié)碼生成子類(lèi)來(lái)處理。這是朋友說(shuō)的,我并沒(méi)自己實(shí)驗(yàn)過(guò),所以也沒(méi)映象,所以開(kāi)始自己動(dòng)手實(shí)踐之:
    java動(dòng)態(tài)代理

    使用方法:

    接口:

    public interface Call {
    void doCall(String doCall);
    }

    public interface Processor {
    void doProcess(String doProcess);
    }

    實(shí)現(xiàn)類(lèi):

    public class ServiceImpl implements Call, Processor {

    public void doCall(String doCall) {
    System.out.println("doCall");
    }

    public void doProcess(String doProcess) {
    System.out.println("doProcess");
    }
    }

    具體代理Handler:

    public class ServiceHandler implements InvocationHandler {

    private Call callService;

    public ServiceHandler(Call callService) {
    this.callService = callService;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    System.out.println("proxyMethod=" + method.getName());
    Object obj = method.invoke(this.callService, args);
    System.out.println("after invoke!");
    return obj;
    }

    }

    使用java動(dòng)態(tài)代理:

    public class JdkProxyTest {   
    @Test
    public void testJdkProxy() {
    Call call = new ServiceImpl();
    ServiceHandler handler = new ServiceHandler(call);
    Call callProxy = (Call) Proxy.newProxyInstance(call.getClass().getClassLoader(),
    new Class[]{Call.class}, handler);
    callProxy.doCall("test");
    }
    }

    最終效果就是執(zhí)行代理接口的doCall方法之前,該方法被ServiceHandler給處理了。

    通過(guò)查看java.lang.reflect.Proxy代碼,大致擬了一下它的實(shí)現(xiàn)原理:
    1. 取到new Class[]{Call.class}這里所有接口,通過(guò)Class.forName把接口類(lèi)加載到JVM,放到內(nèi)部Set里保存,把接口的完善名字保存,帶包名的接口名字,并以把這組接口名稱(chēng)數(shù)組轉(zhuǎn)換成List作為key,用于下面生成代理類(lèi)后保存到內(nèi)部Map的key.也就是相當(dāng)于這一組的接口名稱(chēng)對(duì)應(yīng)的一個(gè)生成的代理類(lèi)
    2. 主要是從內(nèi)存里找是否之前已經(jīng)生成好了這同一組接口的代理類(lèi),如果有就直接拿出。這里第一次是需要新建立的,所以開(kāi)始創(chuàng)建代理,首先檢查代理目標(biāo)接口的訪(fǎng)問(wèn)控制符是否是默認(rèn)包級(jí)別的,如果是就需要給生成的代理類(lèi)設(shè)置目標(biāo)接口同樣的包名,才能默認(rèn)訪(fǎng)問(wèn)這種級(jí)別下的接口。如果這種有默認(rèn)訪(fǎng)問(wèn)控制標(biāo)識(shí)符的目標(biāo)接口,又有不同包名的目標(biāo)接口,則會(huì)報(bào)出錯(cuò)誤。否則其它情況,是給的無(wú)包名的代理類(lèi),生成的代理類(lèi)的默認(rèn)名稱(chēng)是$Proxy開(kāi)頭加Proxy里標(biāo)識(shí)唯一類(lèi)名的數(shù)字,是靜態(tài)long型變量,每次生成一次代理類(lèi)會(huì)累加
    3. 調(diào)用ProxyGenerator.generateProxyClass(proxyName, interfaces)動(dòng)態(tài)生成class字節(jié)碼類(lèi),該類(lèi)相當(dāng)于是Proxy的子類(lèi),實(shí)現(xiàn)了需要代理的接口方法,并在每個(gè)方法里調(diào)用了InvocationHandler的invoke方法,而我們自己實(shí)現(xiàn)的InvocationHandler接口類(lèi)里完成了以反射方式最終對(duì)目標(biāo)業(yè)務(wù)類(lèi)的接口方法進(jìn)行調(diào)用。所以此種方式實(shí)現(xiàn)的動(dòng)態(tài)代理只能代理接口方法,對(duì)具體類(lèi)的代理不能實(shí)現(xiàn)。

     

    http://hi.baidu.com/dobug/blog/item/493f817e802479340cd7dab9.html

    posted on 2012-06-07 21:51 abin 閱讀(706) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): java基礎(chǔ)知識(shí)

    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 四虎永久在线观看免费网站网址| 国产大片免费观看中文字幕| 色在线亚洲视频www| 国产美女无遮挡免费视频| 国产国产人免费人成成免视频 | 好吊妞视频免费视频| 免费人成再在线观看网站| 亚洲第一中文字幕| 日本高清免费不卡在线| 三年片在线观看免费西瓜视频| 亚洲一线产区二线产区精华| 亚洲黄片毛片在线观看| 久久www免费人成看片| 一本到卡二卡三卡免费高 | 三级毛片在线免费观看| 精品亚洲成在人线AV无码| 亚洲真人无码永久在线| 最近免费中文字幕大全视频 | 亚洲乱码中文论理电影| 国产亚洲?V无码?V男人的天堂 | 亚洲综合综合在线| www国产亚洲精品久久久日本| 91久久精品国产免费一区| 一个人免费播放在线视频看片| 国产精品亚洲片夜色在线| 国产亚洲精品va在线| 国产精品黄页在线播放免费| 免费女人高潮流视频在线观看| 国产亚洲视频在线| 亚洲日日做天天做日日谢| 久久久久亚洲AV成人无码| 亚洲 无码 在线 专区| 久久电影网午夜鲁丝片免费| 午夜免费啪视频在线观看 | 亚洲熟女少妇一区二区| 免费国产在线观看老王影院| 成人免费激情视频| 最近最新高清免费中文字幕| 中文字幕不卡免费视频| 一级毛片大全免费播放下载| 亚洲精品国产高清在线观看|