生成代理类:
Class proxyClass = Proxy.getProxyClass(ClassLoader loader, Class ... interfaces);
这段代码生成一个代理类,该代理类拥有一个参数类型为InvocationHandler的构造方法,用以构造代理对象,如下:
Object proxyInstance = proxyClass.getConstructor(InvocationHandler.class).newInstance(new MyInvocationHandler(...));
以上步骤合并,就可以是以下更简单的形式:
Object proxyInstance = Proxy.newInstance(ClassLoader loader, Class [] interfaces, InvocationHandler h);
其中的原理:
1、生成代理类字节码:byte[] proxyClassFile = ProxyGenerator.generateProxyClass(String proxyName, Class [] interfaces, int accessFlags);
这里ProxyGenerator.generateProxyClass方法直接根据指定的代理类名称、接口列表和类的访问修饰符生成代理类的字节码文件;
生成的代理类会继承java.lang.reflect.Proxy类,实现参数指定的接口。代理类会实现所有接口方法并覆盖Object的equals、hashCode、toString方法。 代理类本身和它定义的所有方法都是final的,包括equals、hashCode、toString。 2、代理类中的每个方法,都有一个static Method对象与之关联,包括:equals、hashCode、toString,在这里我理解Method对象仅仅是一个方法描述符而已,它描述了方法的名称、形参列表、返回值、访问标识符和声明这个方法的Class等信息。 3、根据以上代理对象生成代码,在生成代理对象时需要传入一个InvocationHandler对象,在代理类中,对所有方法的调用都会通过以下代码委托到对InvocationHandler对象的调用: super.h.invoke(this, method, new Object[] { ... }); 其中super.h是指Proxy类中的h属性字段,就是生成代理对象时传入的InvocationHandler对象; 参数1为代理对象本身,参数2为调用的方法对象(对应于代理对象中声明的相应static Method对象),参数3为调用的方法的参数数组。代理类示例(生成字节码后通过jad反编译后调整格式):
package why.jvm.dynamicProxy;import java.lang.reflect.*;import why.jvm.dynamicProxy.FinaTradeService;public final class MyProxyClass extends Proxy implements FinaTradeService { private static Method m1; private static Method m3; private static Method m2; private static Method m4; private static Method m0; static { try { m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); 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("why.jvm.dynamicProxy.FinaTradeService").getMethod("placeOrder", new Class[] { Class.forName("java.lang.String") }); m4 = Class.forName("why.jvm.dynamicProxy.FinaTradeService").getMethod("createOrder", new Class[] { Class.forName("java.lang.String") }); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } public MyProxyClass(InvocationHandler invocationhandler) { super(invocationhandler); } public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } 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); } } public final String toString() { try { return (String) super.h.invoke(this, m2, null); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String createOrder(String s) { try { return (String) super.h.invoke(this, m4, new Object[] { s }); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String placeOrder(String s) { try { return (String) super.h.invoke(this, m3, new Object[] { s }); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } }}