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

http://blog.csdn.net/zhao1991abc/article/details/52926620

posted on 2017-07-01 19:08  bijian1013  阅读(1840)  评论(0编辑  收藏  举报

导航