国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java 動(dòng)態(tài)代理 理解

3fuyu / 3269人閱讀

摘要:之后通過(guò)類的靜態(tài)方法取得一個(gè)代理類實(shí)例再次鄙視自己。值得一提,動(dòng)態(tài)代理把也代理了。總結(jié)動(dòng)態(tài)代理優(yōu)點(diǎn)相比靜態(tài)代理,不用每代理一個(gè)類就得寫一個(gè)新的代理類。缺點(diǎn)只能代理實(shí)現(xiàn)了接口的類,因?yàn)槭菃卫^承,代理類已經(jīng)是類的子類了。

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

這里暫時(shí)只做JDK動(dòng)態(tài)代理分析。動(dòng)態(tài)代理應(yīng)用廣泛,例如AOP。




吐槽自己一下,設(shè)計(jì)的類,接口名不是很好。。anyway,大致就是這樣。根據(jù)規(guī)范,Mama類實(shí)現(xiàn)InvocationHandler接口,實(shí)現(xiàn)invoke方法。之后通過(guò)Proxy類的靜態(tài)方法newProxyInstance取得一個(gè)代理類實(shí)例eat(再次鄙視自己)。當(dāng)eat.eat()時(shí),調(diào)用了Mama的invoke方法。
很好奇,源碼是如何實(shí)現(xiàn)代理的。值得一提,JDK動(dòng)態(tài)代理把equals(),toString(),hashCode()也代理了。

源碼分析


一路debug發(fā)現(xiàn),最后調(diào)用了Proxy類下內(nèi)部類ProxyClassFactory的apply方法,其中包含的下列代碼最終動(dòng)態(tài)地創(chuàng)建了proxy class 文件

這時(shí)我們反編譯看看,最后編譯成功的proxy class

public final class KidProxy extends Proxy implements Eat {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public KidProxy(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void eat() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m3 = Class.forName("com.ProxyDemo.Eat").getMethod("eat", new Class[0]);
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

通過(guò)構(gòu)造函數(shù)KidProxy(InvocationHandler var1)初始化類instance,這個(gè)super(var1)即是Proxy的構(gòu)造函數(shù)Proxy(InvocationHandler invocationHandler)即是靜態(tài)方法newProxyInstance傳過(guò)去的參數(shù)。具體的調(diào)用又是在newProxyInstance方法中的最后一句

return cons.newInstance(new Object[]{h});

可知是通過(guò)反射實(shí)例化proxy對(duì)象的,同樣的在構(gòu)造proxy class文件時(shí),也是通過(guò)反射,通過(guò)其實(shí)現(xiàn)的interfaces的具體方法將需要實(shí)現(xiàn)的method寫入proxy class文件的。在記載class文件時(shí),通過(guò)static構(gòu)建method。

static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m3 = Class.forName("com.ProxyDemo.Eat").getMethod("eat", new Class[0]);
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }

其中m3就是我要代理的方法。具體調(diào)用的時(shí)候,通過(guò)將方法delegate給invocationHandler實(shí)例。

總結(jié)

JDK動(dòng)態(tài)代理
優(yōu)點(diǎn)

相比靜態(tài)代理,不用每代理一個(gè)類就得寫一個(gè)新的代理類。
缺點(diǎn)

只能代理實(shí)現(xiàn)了interface接口的類,因?yàn)閖ava是單繼承,代理類已經(jīng)是Proxy類的子類了。實(shí)現(xiàn)代理沒(méi)有實(shí)現(xiàn)接口的類,還得靠ASM技術(shù)。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/70352.html

相關(guān)文章

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

    摘要:這種語(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)代理...

    2shou 評(píng)論0 收藏0
  • 你真的完全了解Java動(dòng)態(tài)代理嗎?看這篇就夠了

    摘要:動(dòng)態(tài)地代理,可以猜測(cè)一下它的含義,在運(yùn)行時(shí)動(dòng)態(tài)地對(duì)某些東西代理,代理它做了其他事情。所以動(dòng)態(tài)代理的內(nèi)容重點(diǎn)就是這個(gè)。所以下一篇我們來(lái)細(xì)致了解下的到底是怎么使用動(dòng)態(tài)代理的。 之前講了《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》,本來(lái)打算下一篇講講Srping的AOP的,但是其中會(huì)涉及到Java的動(dòng)態(tài)代理,所以先單獨(dú)一篇來(lái)了解下Java的動(dòng)態(tài)代理到底是什么,Java是怎么實(shí)現(xiàn)它的。 ...

    haitiancoder 評(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
  • JAVA代理模式的理解和應(yīng)用

    摘要:代理模式代理模式通俗一點(diǎn)的解釋就是在操作一個(gè)對(duì)象和對(duì)象中的方法時(shí),不是直接操作這個(gè)對(duì)象,還是通過(guò)一個(gè)代理對(duì)象來(lái)操作這個(gè)實(shí)際的目標(biāo)對(duì)象。 代理模式: 代理模式通俗一點(diǎn)的解釋就是在操作一個(gè)對(duì)象和對(duì)象中的方法時(shí),不是直接操作這個(gè)對(duì)象,還是通過(guò)一個(gè)代理對(duì)象來(lái)操作這個(gè)實(shí)際的目標(biāo)對(duì)象。應(yīng)用場(chǎng)景一般是需要在執(zhí)行某個(gè)已經(jīng)寫好的方法前后再添加一段邏輯,比如執(zhí)行方法前打印日志,或者在執(zhí)行方法之前和之后打時(shí)...

    CatalpaFlat 評(píng)論0 收藏0
  • 10分鐘看懂動(dòng)態(tài)代理設(shè)計(jì)模式

    摘要:動(dòng)態(tài)代理是語(yǔ)言中非常經(jīng)典的一種設(shè)計(jì)模式,也是所有設(shè)計(jì)模式中最難理解的一種。本文將通過(guò)一個(gè)簡(jiǎn)單的例子模擬動(dòng)態(tài)代理實(shí)現(xiàn),讓你徹底明白動(dòng)態(tài)代理設(shè)計(jì)模式的本質(zhì),文章中可能會(huì)涉及到一些你沒(méi)有學(xué)習(xí)過(guò)的知識(shí)點(diǎn)或概念。 動(dòng)態(tài)代理是Java語(yǔ)言中非常經(jīng)典的一種設(shè)計(jì)模式,也是所有設(shè)計(jì)模式中最難理解的一種。本文將通過(guò)一個(gè)簡(jiǎn)單的例子模擬JDK動(dòng)態(tài)代理實(shí)現(xiàn),讓你徹底明白動(dòng)態(tài)代理設(shè)計(jì)模式的本質(zhì),文章中可能會(huì)涉及到...

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

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

0條評(píng)論

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