首先我们先定义一个接口:
public interface PersonInter { String test(String str); }接着就是我们想的要生成的JDK代理类源码的代码:
public class JdkProxySourceClass { public static void writeClassToDisk(String path){ byte[] classFile = ProxyGenerator.generateProxyClass("$proxy4", new Class[]{PersonInter.class}); FileOutputStream fos = null; try { fos = new FileOutputStream(path); fos.write(classFile); fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void testGenerateProxyClass() { JdkProxySourceClass.writeClassToDisk("D:/$Proxy4.class"); } }重要的就是这一句话:byte[] classFile = ProxyGenerator.generateProxyClass("$proxy4", new Class[]{PersonInter.class});
OK接下来我们用反编译工具看一下生成的代理类源码:
import com.zkn.newlearn.gof.proxyhandler.PersonInter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class Proxy4 extends Proxy implements PersonInter { private static Method m1; private static Method m2; private static Method m3; private static Method m0; public Proxy4(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); } public final boolean equals(Object paramObject) throws { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() throws { try { return ((String)this.h.invoke(this, m2, null)); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String test(String paramString) throws { try { return ((String)this.h.invoke(this, m3, new Object[] { paramString })); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() throws { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { 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("com.zkn.newlearn.gof.proxyhandler.PersonInter").getMethod("test", new Class[] { Class.forName("java.lang.String") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } }
从反编译出来的源码中我们可以看到在静态代码块中得到了equals、toString、hashCode和PersonInter接口中test方法的Method对象。当我们调用PersonInter中的test方法的时候:
public final String test(String paramString) throws { try { return ((String)this.h.invoke(this, m3, new Object[] { paramString })); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } }
其实是调用了InvocationHandler中的invoke方法,并传入了之前获取到的对应的Method和参数。在这里也简单的说一下为什么JDK的动态代理只能代理接口不能代理类,请注意看我们所得到的代理类的源码,注意看这一句:public final class Proxy4 extends Proxy implements PersonInter。生成的代理类默认继承了Proxy这个类,而java中又是单继承的,所以这里只能代理接口,不能代理类了。就像枚举类,不能继承别的枚举类一样。