Proxy 動態代理再次理解

來源:互聯網
上載者:User
package reflect;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import static java.lang.System.out;interface User{public abstract void say(String str);}class UUU implements User{@Overridepublic void say(String str) {out.print(str);}}public class ProxyTest {public   Object target = null;public static void main(String args[])throws Exception {//System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"); // 通過此語句得到動態產生 的class 檔案,然後通過 反編譯工具得到代碼 User prox = (User)(new ProxyTest().bind(new UUU()));// 動態得到 proxy類,這個類繼承proxy,且實現User 介面}public static void  proxyConstruct()throws Exception{Class<?> clazz =  Proxy.getProxyClass(Comparable.class.getClassLoader(),Comparable.class);Constructor cons = clazz.getConstructor(InvocationHandler.class);Object proxy = cons.newInstance(new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {return null;}});out.println(proxy.toString());}public static void proxyInstance()throws Exception {Object proxy = Proxy.newProxyInstance(Comparable.class.getClassLoader(),new Class<?>[] {Comparable.class},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}});out.println(proxy==null);}public Object bind(final Object target){this.target = target ;return Proxy.newProxyInstance(Comparable.class.getClassLoader(),new Class<?>[] {Comparable.class},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {out.println("begin:");return method.invoke(target, args); // 對於代理所執行的任何方法都將轉移到這個地址執行,這也是就為什麼可以添加功能的原因 }});}}/* * Proxy 原理  *  Proxy 就是動態產生一個,其實 這和代理並沒有什麼關係,它只是可以動態地去產生一個類,在產生 *  這個類的時候,我們可以規定它的載入器,實現的介面,而Proxy 產生的這個類並代理目標類做什麼,所以裡面還有一個重要的成員 InvocationHandler h *  *  下面我們來分析一下  目標類(target)、代理類(proxy)、InvocationHandler(Handler)類 它們之間的關係  *  * 當我們調用代理類中實現介面的方法時,如proxy.add(),會將方法名傳給 代理類的 InvocationHandler 成員,而這個成員有一個 invoke 方法,所以我們 * 調用 proxy.add 則成了 h.invoke(this,method,args);而調用h.invoke方法,又不得不調用我們實現的invocationHandler介面裡面的 invoke 方法, * 而我們則在 handler.invoke 方法中調用 根據傳過來的方法Method調用  Method.invoke(target,args),即,這樣就成功調用了目標類裡的方法 *  * 因為代理類調用的所有的方法都變了 h.invoke(proxy,method,args)調用方法,而在invoke 中又知道了方法的method ,即讓方法調用對象 method.invoke(target,args) * 因為代理類始終是自己,所以就變成了h.inovoke(this,method,args) *  * */

下面是反編譯得到的動態類,實現Comparable 介面

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;public final class Proxy0 extends Proxy  implements Comparable{  private static Method m3;  private static Method m1;  private static Method m0;  private static Method m2;  public Proxy0()    throws   {    super(paramInvocationHandler);  }  public final int compareTo()    throws   {    try    {      return ((Integer)this.h.invoke(this, m3, new Object[] { paramObject })).intValue();    }    catch (RuntimeException localRuntimeException)    {      throw localRuntimeException;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  public final boolean equals()    throws   {    try    {      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();    }    catch (RuntimeException localRuntimeException)    {      throw localRuntimeException;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  public final int hashCode()    throws   {    try    {      return ((Integer)this.h.invoke(this, m0, null)).intValue();    }    catch (RuntimeException localRuntimeException)    {      throw localRuntimeException;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  public final String toString()    throws   {    try    {      return ((String)this.h.invoke(this, m2, null));    }    catch (RuntimeException localRuntimeException)    {      throw localRuntimeException;    }    catch (Throwable localThrowable)    {      throw new UndeclaredThrowableException(localThrowable);    }  }  static  {    try    {      m3 = Class.forName("java.lang.Comparable").getMethod("compareTo", new Class[] { Class.forName("java.lang.Object") });      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);      return;    }    catch (NoSuchMethodException localNoSuchMethodException)    {      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());    }    catch (ClassNotFoundException localClassNotFoundException)    {      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());    }  }}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.