轉自:https://www.jianshu.com/p/774c65290218
1. 關於動態代理的一些疑問
學習動態代理時,總是會有疑問,使用代理對象調用我們自己的接口中的方法時,會執行InvocationHandler實現類的invoke()方法,並且返回值與接口的實現類的返回值沒有必然關系等等,出現了很多很奇怪的事情。
接口代碼:
public interface Dao { public void show (); public Object show2(); } class DaoImpl implements Dao { @Override public void show() { System.out.println("我是show()"); } @Override public Object show2() { System.out.println("我是show2()"); return "111"; } }
動態代理代碼:
public class Demo { @Test public void show() { Dao dao = new DaoImpl(); InvocationHandler h = new DaoHandler(dao); Class[] interfaces = { Dao.class }; Dao d = (Dao) Proxy.newProxyInstance(this.getClass().getClassLoader(), interfaces, h); System.out.println(d.show2()); } } class DaoHandler implements InvocationHandler { Dao dao = null; public DaoHandler(Dao dao) { super(); this.dao = dao; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理開始"); Object result = method.invoke(dao); System.out.println("代理結束"); return null; } }
代理對象調用show()方法

show方法.png
代理對象調用show2()方法

show2方法.png
實在忍耐不住好奇心,自己看了看源碼並且再結合百度的分析,大致理解了以下幾點
2. 個人的一些理解
- Proxy.newProxyInstance(//參數省略了...)的部分源碼
//Proxy類開始有這樣的一個定義 private final static Class[] constructorParams = { InvocationHandler.class }; protected InvocationHandler h; protected Proxy(InvocationHandler h) { this.h = h; } public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { // Proxy類的方法getProxyClass,特別長....根據傳入的接口的Class對象與類加載器創建$proxy0類 Class cl = getProxyClass(loader, interfaces); // 通過反射帶參數構造傳入h實例化$proxy0,$proxy0類的帶參構造內部為super(h),其實就是給Proxy的成員h賦值,並返回此對象 Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); }
- 程序運行時產生一個類$proxy0
- $proxy0類繼承自Proxy類,實現了目標對象的父類接口(借鑒的百度提供的源碼)
- $proxy0類有多個Method成員變量,它的靜態代碼塊給Method賦值為我們自己的接口的實現類的對應的Method對象
- $proxy0實現接口的方法調用了super.h.invoke(參數),這里的參數包括Method變量
//$proxy0的源碼 public final class $Proxy0 extends Proxy implements Subject { private static Method m1; private static Method m0; private static Method m3; private static Method m2; static { try { 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]); m3 = Class.forName("接口的實現類的路徑").getMethod("實現類的方法", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } //static public $Proxy0(InvocationHandler invocationhandler) { super(invocationhandler); } @Override public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (