java 将代理对象保存到本地文件
2016-01-14 13:57
573 查看
我们知道,在Java中,常用的动态代理技术有JDK的动态代理和cglib动态代理,但是不管是哪种方式,代理对象都是在程序运行时,运用反射机制动态创建而成,而我们并不能直观的看到生成的代理对象对应的Java源代码。下面,我就提供一种方式,可以将通过动态代理创建的代理对象的字节码文件保存到磁盘,再通过反编译工具查看生成文件的内容,这样就可以加深我们对于代理对象的理解。
JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了,在此,我们以JDK的动态代理为例。
在JDK中提供了一个ProxyGenerator类,可以将代理对象的字节码得到,我们再通过一个输出流就可以将文件保存到磁盘了。
首先定义一个接口:
针对上面接口提供一个实现类:
通过JDK动态代理技术创建代理对象:
通过反编译工具可以查看生成的字节码文件的内容:
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的异常
- [Spring MVC - 2A] - java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
- Java回调的简单理解
- [问答系列一]Java基础知识
- 简单东西-Java不变类编写
- Java字符串常量池的问题
- Spring MVC 的请求参数获取的几种方法
- struts2的DevMode模式
- struts2 配置文件的理解
- JAVA 监控内容收集之 Jmxtrans Agent
- 【Android Studio】Android Studio安装时提示找不到JDK
- Java Web开发技术应用——过滤器
- Java我的高效编程之环境搭建
- Java学习笔记
- Java回调理解 (step by step)
- spring配置dbcp链接数据库
- java批量读取
- Java注释Override、Deprecated、SuppressWarnings详解
- Java线程安全
- java 多线程(5) wait() / notify() 生产者消费者