JDK动态代理生成.class文件
方法一:配置系统属性sun.misc.ProxyGenerator.saveGeneratedFile为true
接口:
package com.bijian.test; public interface IHello { void sayHello(); }
实现类:
package com.bijian.test; public class Hello implements IHello { public void sayHello() { System.out.println("Hello,world!"); } }
InvoctionHandler实现:
package com.bijian.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class HWInvocationHandler implements InvocationHandler { //目标对象 private Object target; public HWInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("------插入前置通知代码-------------"); //执行相应的目标方法 Object rs = method.invoke(target, args); System.out.println("------插入后置处理代码-------------"); return rs; } }
生成代理类,并写入硬盘:配置系统属性sun.misc.ProxyGenerator.saveGeneratedFile为true,代理类生成时将自动将生成的代理类写入硬盘
package com.bijian.test; import java.lang.reflect.Proxy; public class JdkDymamicPoxy { public static void main(String[] args) { //生成$Proxy0的class文件 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); IHello iHello = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), new Class[]{IHello.class} , new HWInvocationHandler(new Hello())); iHello.sayHello(); } }
运行时如报 Exception in thread "main" java.lang.InternalError: I/O exception saving generated file:java.io.FileNotFoundException : com\sun\proxy\$Proxy0.class (系统找不到指定的路径。) 异常时,在项目根目录下增加 com/sun/proxy目录。
方法二:根据类信息和提供的代理类名称,生成字节码,然后通过流的方式写到磁盘文件中
JDK提供了sun.misc.ProxyGenerator.generateProxyClass(String proxyName,class[] interfaces) 底层方法来产生动态代理类的字节码。
下面定义了一个工具类,用来将生成的动态代理类保存到硬盘中。
package com.bijian.jdkproxy; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Proxy; import sun.misc.ProxyGenerator; public class ProxyUtils { /* * 将根据类信息 动态生成的二进制字节码保存到硬盘中, * 默认的是clazz目录下 * params :clazz 需要生成动态代理类的类 * proxyName : 为动态生成的代理类的名称 */ public static void generateClassFile(Class clazz, String proxyName) { //根据类信息和提供的代理类名称,生成字节码 byte[] classFile = ProxyGenerator.generateProxyClass(proxyName, clazz.getInterfaces()); String paths = clazz.getResource(".").getPath(); System.out.println(paths); FileOutputStream out = null; try { //保留到硬盘中 out = new FileOutputStream(paths + proxyName + ".class"); out.write(classFile); out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
如我想将生成的代理类起名为“ElectricCarProxy”,并保存在硬盘,应该使用以下语句:
package com.bijian.jdkproxy; public class ProxyUtilsTest { public static void main(String[] args) { ElectricCar car = new ElectricCar(); ProxyUtils.generateClassFile(car.getClass(), "ElectricCarProxy"); } }
运行后将在ElectricCar.class 同级目录下产生 ElectricCarProxy.class文件。
参考文章:http://www.cnblogs.com/flyingeagle/articles/7102282.html
posted on 2017-07-01 19:08 bijian1013 阅读(1840) 评论(0) 编辑 收藏 举报