我们知道,在Java中,常用的动态代理技术有JDK的动态代理和cglib动态代理,但是不管是哪种方式,代理对象都是在程序运行时,运用反射机制动态创建而成,而我们并不能直观的看到生成的代理对象对应的Java源代码。下面,我就提供一种方式,可以将通过动态代理创建的代理对象的字节码文件保存到磁盘,再通过反编译工具查看生成文件的内容,这样就可以加深我们对于代理对象的理解。
JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了,在此,我们以JDK的动态代理为例。
在JDK中提供了一个ProxyGenerator类,可以将代理对象的字节码得到,我们再通过一个输出流就可以将文件保存到磁盘了。
首先定义一个接口:
package cn.itcast.jdkproxy; public interface IUserDao { public void save(); } |
针对上面接口提供一个实现类:
package cn.itcast.jdkproxy; public class UserDaoImpl implements IUserDao{ public void save() { System.out.println("完成保存操作"); } } |
通过JDK动态代理技术创建代理对象:
package cn.itcast.jdkproxy; import java.io.File; import java.io.FileOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import sun.misc.ProxyGenerator; public class JdkProxyTest { public static void main(String[] args) throws Exception { final IUserDao target = new UserDaoImpl(); IUserDao proxy = (IUserDao) Proxy.newProxyInstance(target.getClass() .getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName()); return method.invoke(target, args); } }); byte[] proxyClass = ProxyGenerator.generateProxyClass(proxy.getClass() .getSimpleName(), proxy.getClass().getInterfaces()); //将字节码文件保存到D盘,文件名为$Proxy0.class FileOutputStream outputStream = new FileOutputStream(new File( "d://$Proxy0.class")); outputStream.write(proxyClass); outputStream.flush(); outputStream.close(); } } |
通过反编译工具可以查看生成的字节码文件的内容:
import cn.itcast.jdkproxy.IUserDao; 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 IUserDao { private static Method m3; private static Method m1; private static Method m0; private static Method m2; public $Proxy0(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); } public final void save() throws { try { this.h.invoke(this, m3, null); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { } throw new UndeclaredThrowableException(localThrowable); } 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 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); } 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); } static { try { m3 = Class.forName("cn.itcast.jdkproxy.IUserDao").getMethod("save", new Class[0]); 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]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { } throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } |
本文版权归传智播客Java培训学院所有,欢迎转载,转载请注明作者出处。谢谢!
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/253047.html