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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国色天香社区在线视频免费观看 | 久久久精品免费免费直播 | 国产精品免费网站 | 久久国产主播福利在线 | 性刺激欧美三级在线现看中文 | 欧美日韩一级视频 | 美女福利视频午夜在线 | 精品国产一级在线观看 | 日韩在线免费看 | 日本一本二本三区免费 | 99re热| 深夜网站在线观看 | 挺进白嫩老师下面视频 | 国产精品日韩欧美一区二区三区 | 国产精品特黄毛片 | 国产成人 免费观看 | 亚洲高清影院 | 亚洲激情综合 | 翁熄性放纵交换300章 | 精品日产1区2卡三卡麻豆 | 成人黄页网站 | 2019国内自拍| 91久色| 亚洲人成网站在线观看播放青青 | 亚洲精品久久碰 | 欧美日本道免费一区二区三区 | 五月婷婷在线观看 | 性关系视频免费网站在线观看 | 国产一区二区三区久久精品 | 精品国产成人a区在线观看 精品国产91久久久久久久 | 亚洲国产一区二区三区a毛片 | 精品久久久久久国产91 | 草莓视频在线观看免费 | 欧美有码| 国产一级视频在线观看 | 四虎永久 | 干露露视频 性感写真 | a亚洲天堂 | 免费看国产一级片 | 国产精品中文 | 国产精品对白刺激久久久 |