JDK动态代理

在上一篇博客中分析了一下JAVA设计模式中的代理模式,其中动态代理中,又有一个十分重要的JDK动态代理,这篇文章主要是分析JDK动态代理究竟是如何实现的。

动态代理实现思路

实现功能:通过Proxy的newProxyInstance返回代理对象。

  1. 声明一段源码(动态产生代理)。
  2. 编译源码(JDK Compiler API),产生新的类(代理类)。
  3. 将这个类load到内存中,产生一个新的对象(代理对象)。
  4. return代理对象。

准备工作:

  1. 引入一个jar包commons-io-2.2.jar。
  2. 将项目中Build Path下的JRE换成JDK,因为JRE不支持编译。

实例:

首先,自定义一个接口InvocationHandler

public interface InvocationHandler {
    
    public void invoke(Object o,Method m);

}

接着定义接口的实现类

public class TimeHandler implements InvocationHandler {
    private Object target;
    public TimeHandler(Object target) {
        super();
        this.target = target;
    }

    @Override
    public void invoke(Object o, Method m){
        try {
            System.out.println("日志开始打印.....");
            m.invoke(target);
            System.out.println("日志结束打印......");
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

编写模拟动态代理实现的类

public class Proxy {
    public static Object newProxyInstance(Class infce,InvocationHandler h) throws Exception{
        //window下的换行符
        String rt = "
";
        String methodStr = "";
        for(Method m : infce.getMethods()){
            methodStr += "@Override" + rt +
            "public void " + m.getName() + "() {" + rt +
                "try{" + rt +
                "Method md = " + infce.getName() + ".class.getMethod(""
                                + m.getName() + "");" + rt +
                "h.invoke(this,md);" + rt +
                "}catch(Exception e){e.printStackTrace();}" + rt +
            "}";
        }
        //声明一段源码
        String str = "package model;" + rt +
                     "import java.lang.reflect.Method;" + rt +
                     "import model.InvocationHandler;" + rt +
                        "public class $Proxy0 implements " + infce.getName() + "{" + rt +
                            "private InvocationHandler h;" + rt +    
                            "public $Proxy0(InvocationHandler h) {" + rt +
                                "super();" + rt +
                                "this.h = h;" + rt +
                            "}" + rt +                    
                            methodStr + rt +
                        "}";
        //产生代理类的java文件
        String filename = System.getProperty("user.dir")+"/src/model/$Proxy0.java";
        File file = new File(filename);
        FileUtils.writeStringToFile(file, str);
        /**
         *编译
         *获取编译器
         */
        JavaCompiler complier = ToolProvider.getSystemJavaCompiler();
        //创建文件管理者    
        StandardJavaFileManager fileMgr = 
                complier.getStandardFileManager(null, null, null);
        //获取文件
        Iterable units = fileMgr.getJavaFileObjects(filename);
        //编译任务
        CompilationTask t = complier.getTask(null, fileMgr, null, null, null, units);
        //进行编译
        t.call();
        fileMgr.close();        
        //load到内存中
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Class c = cl.loadClass("model.$Proxy0");
        //根据构造器初始化,产生代理类
        Constructor ctr = c.getConstructor(InvocationHandler.class);
        return ctr.newInstance(h);
    }
}

最后编写测试类

public class Test {
    /**
     * 测试类
     * */
    public static void main(String[] args) throws Exception {
        Car car = new Car();
        //事务处理
        InvocationHandler h = new TimeHandler(car);
        Moveable m = (Moveable) Proxy.newProxyInstance(Moveable.class,h);
        m.move();
    }
}
原文地址:https://www.cnblogs.com/libinhyq/p/9584262.html