接口: package com.atb.proxy.simple; public interface ProxyInterface { public void methodPrint(); } 实现类: package com.atb.proxy.simple; public class ProxyImple implements ProxyInterface{ private String aa="sss"; public void methodPrint() { System.out.println("hi dubbo:"+aa); } }
下面的是代理类及测试的具体代码
package com.atb.proxy.simple; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 动态代理类 * @author xieronghui */ public class DynamicProxy implements InvocationHandler { // 被代理对象 private Object proxyObject; /** * 绑定委托对象,并返回一个代理类 */ public Object bind(Object proxyObject) { this.proxyObject = proxyObject; /** * 这里是源码的方法描述 loader 代表动态加载的代理对象; * interfaces 接口(一个类我们可以实现多个接口吧这里相当于ProxyInterface) * h InvocationHandler(DynamicProxy 对象 实现了InvocationHandler) * public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) */ return Proxy.newProxyInstance(proxyObject.getClass().getClassLoader(), proxyObject.getClass().getInterfaces(), this); } /** * $Proxy0 调用父类的invoke */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(proxyObject, args); return result; } }
测试对象
package com.atb.proxy.simple; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args) throws SecurityException, NoSuchMethodException { DynamicProxy proxy=new DynamicProxy(); ProxyInterface proxyInter=(ProxyInterface)proxy.bind(new ProxyImple()); //proxyInter.methodPrint(); //这里可以通过运行结果证明proxyInter是Proxy的一个实例,这个实例实现了proxyInter接口 System.out.println(proxyInter instanceof Proxy); //这里可以看出proxyInter的Class类是$Proxy0,这个$Proxy0类继承了Proxy,实现了proxyInter接口 System.out.println("ProxyInterface的Class类是:"+proxyInter.getClass().toString()); System.out.print("ProxyInterface($Proxy0)中的属性有:"); Field[] field=proxyInter.getClass().getDeclaredFields(); for(Field f:field){ System.out.print(f.getName()+", "); } System.out.print("\n"+"ProxyInterface--->($Proxy0)中的方法有:"); Method[] method=proxyInter.getClass().getDeclaredMethods(); for(Method m:method){ System.out.print(m.getName()+", "); } System.out.println("\n"+"ProxyInterface ($Proxy0)的父类是:"+proxyInter.getClass().getSuperclass()); System.out.print("\n"+"ProxyInterface ($Proxy0)实现的接口是:"); Class<?>[] interfaces=proxyInter.getClass().getInterfaces(); for(Class<?> i:interfaces){ System.out.print(i.getName()+", "); } System.out.println("\n"+"#调用的结果:"); proxyInter.methodPrint(); } }
返回结果:
true ProxyInterface的Class类是:class $Proxy0 ProxyInterface($Proxy0)中的属性有:m1, m3, m0, m2, ProxyInterface--->($Proxy0)中的方法有:equals, toString, hashCode, methodPrint, ProxyInterface ($Proxy0)的父类是:class java.lang.reflect.Proxy ProxyInterface ($Proxy0)实现的接口是:com.atb.proxy.simple.ProxyInterface, #调用的结果: hi dubbo:sss
ProxyInterface的Class类是:class $Proxy0 从这里可以看出
ProxyInterface proxyInter=(ProxyInterface)proxy.bind(new ProxyImple());
返回的Class 居然是$Proxy0 并不是 接口实现ProxyImple 的字节码,以前我一直理解是ProxyImple的实例去调用它的方法methodPrint();其实它是通过类加载器动态的构造了$Proxy0 的对象,我们控制台打印可以看出
ProxyInterface--->($Proxy0)中的方法有:equals, toString, hashCode, methodPrint,
ProxyInterface ($Proxy0)的父类是:class java.lang.reflect.Proxy
而$Proxy0 是在什么时候构造出来的呢打开
public Object bind(Object proxyObject) {
this.proxyObject = proxyObject;
/**
* 这里是源码的方法描述 loader 代表动态加载的代理对象;
* interfaces 接口(一个类我们可以实现多个接口吧这里相当于ProxyInterface)
* h InvocationHandler(DynamicProxy 对象 实现了InvocationHandler)
* public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
*/
return Proxy.newProxyInstance(proxyObject.getClass().getClassLoader(),
proxyObject.getClass().getInterfaces(), this);
}
调用的newProxyInstance方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } /* * Look up or generate the designated proxy class. */ Class cl = getProxyClass(loader, interfaces); //这里就动态获取到了$Proxy0对象 /* * Invoke its constructor with the designated invocation handler. */ try { Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); } }
getProxyClass()方法很长,可以直接打开JDK源码学习理解
这里执行了初始化$Proxy0对象 /** prefix for all proxy class names */ private final static String proxyClassNamePrefix = "$Proxy"; String proxyName = proxyPkg + proxyClassNamePrefix + num; /* * Verify that the class loader hasn't already * defined a class with the chosen name. */ /* * Generate the specified proxy class. */ byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces); try { proxyClass = defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
$Proxy0类 实现了interfaces的接口,并继承了Proxy类
类加载器动态创建的$Proxy0
public final class $Proxy0 extends Proxy implements ProxyInterface{ 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("java.lang.Object").getMethod("toString", new Class[0]); m2 = Class.forName(" com.atb.proxy.simple.ProxyImple").getMethod("methodPrint", 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 (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final void methodPrint() { try { super.h.invoke(this, m2, null); return; } catch (Error e) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final String toString() { try { return (String) super.h.invoke(this, m3, null); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } }
我们继续newProxyInstance 方法
Constructor cons = cl.getConstructor(constructorParams); //获取带参构造器 return (Object) cons.newInstance(new Object[] { h }); //实例化 并传参实例 这两句代码相当于 class Proxy{ InvocationHandler h=null; protected Proxy(InvocationHandler h) { this.h = h; } }
总结:实现的InvocationHandler 接口invoke 到底什么时候调用
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(proxyObject, args); return result; }
$Proxy0实例---》ProxyInterface,将引用赋给ProxyInterface。执行ProxyInterface方法时,调用了$Proxy0类中的methodPrint()方法,进而调用父类Proxy中的h的invoke()方法.即InvocationHandler.invoke()。