转自: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 (