java 動態代理

來源:互聯網
上載者:User

標籤:

0x01 描述

”動態代理中的動態,是針對使用java代碼實際編寫了代理類的“靜態”代理而言的,它的優勢不在於省去了編寫代理類的那一點工作量,而是實現了可以在原始類和介面還未知的時候,就可以確定代理類的行為,當代理類與原始類脫離直接聯絡後,就可以很靈活地重用於不同的應用情境中"  引自 《深入理解java虛擬機器 java進階特性與最佳實務》。

它的缺點:因為java中類只支援單繼承,而代理類有個共同的父類Proxy,所有註定了動態代理不能為類成員方法作代理的缺陷。

0x02 demo
package test;public interface IWorker {    Object work(Object... objects);}
package test;public class Worker implements IWorker {    @Override    public Object work(Object... objects) {        System.out.println("Working ...");        return "work method";    }}
package test;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class Handler implements InvocationHandler {    IWorker mWorker;    Handler(IWorker iWorker) {        this.mWorker = iWorker;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        if (method.getName().equals("equals")) {            System.out.println("the equals method will always return true");            return true;        } else if (method.getName().equals("hashCode")) {            System.out.println("yes, the hashCode is ");        } else if (method.getName().equals("toString")) {            System.out.println("toString method has been called");        }        return method.invoke(mWorker, args);    }}
package test;import java.lang.reflect.Proxy;public class Test {    public static void main(String[] args) {        System.getProperties().put(                "sun.misc.ProxyGenerator.saveGeneratedFiles", "true");        IWorker worker = (IWorker) Proxy.newProxyInstance(                IWorker.class.getClassLoader(), Worker.class.getInterfaces(),                new Handler(new Worker()));        System.out.println(worker.work());        System.out.println(worker.equals(null));        System.out.println(worker.toString());        System.out.println(worker.hashCode());    }}

0x03 動態產生的代理類的代碼

package com.sun.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;import test.IWorker;public final class $Proxy0  extends Proxy  implements IWorker{  private static Method m1;  private static Method m2;  private static Method m3;  private static Method m0;    public $Proxy0(InvocationHandler paramInvocationHandler)    throws   {    super(paramInvocationHandler);  }    public final boolean equals(Object paramObject)    throws   {    try    {      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }    public final String toString()    throws   {    try    {      return (String)this.h.invoke(this, m2, null);    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }    public final Object work(Object[] paramArrayOfObject)    throws   {    try    {      return (Object)this.h.invoke(this, m3, new Object[] { paramArrayOfObject });    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }    public final int hashCode()    throws   {    try    {      return ((Integer)this.h.invoke(this, m0, null)).intValue();    }    catch (Error|RuntimeException localError)    {      throw localError;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }    static  {    try    {      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);      m3 = Class.forName("test.IWorker").getMethod("work", new Class[] { Class.forName("[Ljava.lang.Object;") });      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);      return;    }    catch (NoSuchMethodException localNoSuchMethodException)    {      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());    }    catch (ClassNotFoundException localClassNotFoundException)    {      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());    }  }}
 0x04 注意

1、動態產生的方法都是final的

2、除了介面中的方法外,預設它還覆蓋了Object類中的toString、hashCode和equals方法

3、每個方法都進行了異常的捕捉,雖然對異常進行了簡單的分類處理,但是仍然使用了奇怪的文法將捕捉到的運行時異常照常拋出,所以在使用到代理類的地方照樣可以使用正常的異常出來邏輯來處理運行時拋出的異常

java 動態代理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.