java.lang.reflect.Proxy类是通过创建一个新的Java类(类名为com.sun.proxy.$ProxyXXX)的方式来实现无侵入的类方法代理功能的。
动态代理生成出来的类有如下技术细节和特性:
- 动态代理的必须是接口类,通过
动态生成一个接口实现类来代理接口的方法调用(反射机制)。 - 动态代理类会由
java.lang.reflect.Proxy.ProxyClassFactory创建。 ProxyClassFactory会调用sun.misc.ProxyGenerator类生成该类的字节码,并调用java.lang.reflect.Proxy.defineClass0()方法将该类注册到JVM。- 该类继承于
java.lang.reflect.Proxy并实现了需要被代理的接口类,因为java.lang.reflect.Proxy类实现了java.io.Serializable接口,所以被代理的类支持序列化/反序列化。 - 该类实现了代理接口类(示例中的接口类是
com.anbai.sec.proxy.FileSystem),会通过ProxyGenerator动态生成接口类(FileSystem)的所有方法, - 该类因为实现了代理的接口类,所以当前类是代理的接口类的实例(
proxyInstance instanceof FileSystem为true),但不是代理接口类的实现类的实例(proxyInstance instanceof UnixFileSystem为false)。 - 该类方法中包含了被代理的接口类的所有方法,通过调用动态代理处理类(
InvocationHandler)的invoke方法获取方法执行结果。 - 该类代理的方式重写了
java.lang.Object类的toString、hashCode、equals方法。 - 如果动过动态代理生成了多个动态代理类,新生成的类名中的
0会自增,如com.sun.proxy.$Proxy0/$Proxy1/$Proxy2。
动态代理生成的com.sun.proxy.$Proxy0类代码:
package com.sun.proxy.$Proxy0;import java.io.File;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 FileSystem {private static Method m1;// 实现的FileSystem接口方法,如果FileSystem里面有多个方法那么在这个类中将从m3开始n个成员变量private static Method m3;private static Method m0;private static Method m2;public $Proxy0(InvocationHandler var1) {super(var1);}public final boolean equals(Object var1) {try {return (Boolean) super.h.invoke(this, m1, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final String[] list(File var1) {try {return (String[]) super.h.invoke(this, m3, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final int hashCode() {try {return (Integer) super.h.invoke(this, m0, (Object[]) null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final String toString() {try {return (String) super.h.invoke(this, m2, (Object[]) null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}static {try {m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m3 = Class.forName("com.anbai.sec.proxy.FileSystem").getMethod("list", Class.forName("java.io.File"));m0 = Class.forName("java.lang.Object").getMethod("hashCode");m2 = Class.forName("java.lang.Object").getMethod("toString");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}}
