国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

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

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方法。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品不卡一区 | 日韩国产精品一区二区 | 91网页版 | 午夜精品视频在线观看 | 亚洲精品日韩精品 | 黄色在线免费观看视频网站 | 欧美日韩在线电影 | 免费成人在线网站 | www夜夜操 | 欧美日韩精品一区二区三区四区 | 日韩视频在线一区二区 | 91精品国产综合久久久久久丝袜 | 日本一区二区在线免费 | 欧美一级精品片在线看 | 中文字幕 国产精品 | 久久久久久久一区 | 97久久超碰 | 在线观看的av | 青青草免费在线视频 | 国产乱码精品一区二区三区忘忧草 | 国产精品毛片久久久久久 | 国产日韩精品在线 | 91亚洲国产成人久久精品网站 | 国产精品久久久久久吹潮 | 久久中文字幕一区 | 亚洲一区二区在线看 | 91久久久久久久久 | 亚洲一视频 | 亚洲成人精品一区 | 亚洲精品无码专区在线播放 | 国产三级一区 | 中文字幕在线一区二区三区 | 中文字幕在线免费 | 国产成人久久av免费高清密臂 | 国产精品久久久久久久久久久久冷 | 国产日韩欧美 | 国产目拍亚洲精品99久久精品 | 欧美日韩精品久久久 | 欧美精品黄色 | 久久亚洲二区 | 成人午夜精品久久久久久久3d |