一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java jdk動態代理詳解

java jdk動態代理詳解

2019-10-14 13:54java技術網 Java教程

動態代理類的Class實例是怎么生成的呢,是通過ProxyGenerator類來生成動態代理類的class字節流,把它載入方法區

jdk動態代理要對一個類進行代理,被代理的類必須實現至少一個接口,并且只有接口中的方法才能被代理。

jdk實現動態代理一般分為三步:

1. 編寫接口和實現類。

2. 寫一個處理器,該處理器實現InvocationHandler接口,該接口只有一個方法,其簽名為public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;可在該處理器的實現方法中,在方法調用前和調用后加入自己的代碼,從而進行動態攔截。要注意的是proxy為生成的動態代理類,并不是真的我們被代理的類,所以可在處理器中加入Object類型的成員變量,指向我們真正要求被代理的類(即第1步中的實現類)。

3. 使用java.lang.reflect.Proxy類的newProxyInstance方法生成動態代理類。對所有要代理方法的調用,都是直接調用生成的動態代理類的方法即可,但是要先對它進行強制類型轉換,轉換成我們要調用的方法的接口。

JDK原理分析:
通過分析Proxy的源代碼,可看到動態代理類的詳細生成。newProxyInstance方法首先生成動態代理類的Class實例,再調用它的參數類型為InvocationHandler的構造函數來生成動態代理類并返回。

動態代理類的Class實例是怎么生成的呢,是通過ProxyGenerator類來生成動態代理類的class字節流,把它載入方法區。

分析class字節流生成的過程可以看到它使用Proxy為它的父類,實現所有要代理的接口的方法,每個方法的實現體里主要都是調用處理器的invoke方法。

class字節流的生成過程的主要代碼如下:

復制代碼代碼如下:


private byte[] generateClassFile()
    {
        addProxyMethod(hashCodeMethod, java/lang/Object);
        addProxyMethod(equalsMethod, java/lang/Object);
        addProxyMethod(toStringMethod, java/lang/Object);
        for(int i = 0; i < interfaces.length; i++)
        {
            Method amethod[] = interfaces[i].getMethods();
            for(int k = 0; k < amethod.length; k++)
                addProxyMethod(amethod[k], interfaces[i]);

 

        }

        List list;
        for(Iterator iterator = proxyMethods.values().iterator(); iterator.hasNext(); checkReturnTypes(list))
            list = (List)iterator.next();

        try
        {
            methods.add(generateConstructor());
            for(Iterator iterator1 = proxyMethods.values().iterator(); iterator1.hasNext();)
            {
                List list1 = (List)iterator1.next();
                Iterator iterator2 = list1.iterator();
                while(iterator2.hasNext()) 
                {
                    ProxyMethod proxymethod = (ProxyMethod)iterator2.next();
                    fields.add(new FieldInfo(proxymethod.methodFieldName, "Ljava/lang/reflect/Method;", 10));
                    methods.add(<SPAN style="COLOR: red">proxymethod.generateMethod()</SPAN><SPAN style="COLOR: #000000">);</SPAN>        

 

復制代碼代碼如下:

        }  
    }  

    methods.add(generateStaticInitializer());  
}  
catch(IOException ioexception)  
{  
    throw new InternalError("unexpected I/O Exception");  
}  
if(methods.size() > 65535)  
    throw new IllegalArgumentException("method limit exceeded");  
if(fields.size() > 65535)  
    throw new IllegalArgumentException("field limit exceeded");  
cp.getClass(dotToSlash(className));  
cp.getClass("java/lang/reflect/Proxy");  
for(int j = 0; j < interfaces.length; j++)  
    cp.getClass(dotToSlash(interfaces[j].getName()));  

cp.setReadOnly();  
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();  
DataOutputStream dataoutputstream = new DataOutputStream(bytearrayoutputstream);  
try  
{  
    dataoutputstream.writeInt(-889275714);  
    dataoutputstream.writeShort(0);  
    dataoutputstream.writeShort(49);  
    cp.write(dataoutputstream);  
    dataoutputstream.writeShort(49);  
    dataoutputstream.writeShort(cp.getClass(dotToSlash(className)));  
    dataoutputstream.writeShort(cp.getClass("java/lang/reflect/Proxy"));  
    dataoutputstream.writeShort(interfaces.length);  
    for(int l = 0; l < interfaces.length; l++)  
        dataoutputstream.writeShort(cp.getClass(dotToSlash(interfaces[l].getName())));  

    dataoutputstream.writeShort(fields.size());  
    FieldInfo fieldinfo;  

 

復制代碼代碼如下:


//添加屬性
for(Iterator iterator3 = fields.iterator(); iterator3.hasNext(); fieldinfo.write(dataoutputstream))

 

fieldinfo = (FieldInfo)iterator3.next();
            //添加方法
            dataoutputstream.writeShort(methods.size());
            MethodInfo methodinfo;
            for(Iterator iterator4 = methods.iterator(); iterator4.hasNext(); methodinfo.write(dataoutputstream))
                methodinfo = (MethodInfo)iterator4.next();

            dataoutputstream.writeShort(0);
        }
        catch(IOException ioexception1)
        {
            throw new InternalError("unexpected I/O Exception");
        }
        return bytearrayoutputstream.toByteArray();
    }

 


注:代碼中加紅部分proxymethod.generateMethod()為每個方法生成方法體,通過查看源碼可以看出都是在調用InvocationHandler接口的實現處理器的invoke方法。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚欧洲乱码视频一二三区 | 午夜宅男影院 | 99热这里只有精品在线播放 | 亚洲成综合人影院在院播放 | a男人的天堂久久a毛片 | 午夜AV亚洲一码二中文字幕青青 | 东北老妇露脸xxxxx | 日本高清视频在线的 | 国产精品久线观看视频 | 黑人干我| 国产专区一va亚洲v天堂 | 欧美日本一道高清二区三区 | 99re7在线精品免费视频 | 日本偷拍xxxxxxww | 亚洲精品国产自在现线最新 | 天美视频在线 | 蜜桃88av| yy111111影院理论大片 | 欧美日韩国产一区二区三区在线观看 | a及毛片 | 亚洲精品综合一区二区 | 色综合久久天天综合 | 狠狠色狠狠色综合曰曰 | 青青青久在线视频免费观看 | 大学生初次破苞免费视频 | 三级欧美在线 | 日韩日日操| 国产欧美日韩不卡 | 福利一区在线观看 | 高清不卡免费一区二区三区 | 国产成人激情 | 亚洲乱亚洲乱妇41p 亚洲乱码一区二区三区国产精品 | 亚洲国产成人久久99精品 | 网红刘婷hd国产高清 | 国产高清在线精品一区 | 成年视频在线观看免费 | 国产主播福利在线观看 | 亚洲国产高清一区二区三区 | 天天综合色天天综合色sb | 国产成人夜色影视视频 | 国产人va在线 |