模拟实现JDK动态代理

要模拟动态代理实现必须引入一个commons-io 包 用于创建java文件

首先我们创建一个被代理类:car 车辆

package com.zs.spring.demo2;


import java.util.Random;

public class Car implements Moveable {

    @Override
    public void move() {
        //实现开车
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

创建一个行驶的接口类

package com.zs.spring.demo2;

public interface Moveable {
    public void move() ;
}

//创建一个事务代理类接口

package com.zs.spring.demo2;

import java.lang.reflect.Method;

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

创建一个记录行驶时间的事务处理器实现 InvocationHandler 接口

package com.zs.spring.demo2;

import java.lang.reflect.Method;

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 {
            long starttime = System.currentTimeMillis();
            System.out.println("汽车开始行驶....");
            m.invoke(target);
            long endtime = System.currentTimeMillis();
            System.out.println("汽车结束行驶....  汽车行驶时间:"
                            + (endtime - starttime) + "毫秒!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

创建动态代理类

package com.zs.spring.demo2;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;

import org.apache.commons.io.FileUtils;

public class Proxy {
    @SuppressWarnings("unchecked")
    public static Object newProxyInstance(Class infce,InvocationHandler h) throws Exception{
        String rt = "\r\n";
        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 com.zs.spring.demo2;" + rt +
        "import java.lang.reflect.Method;" + rt +
        "import com.zs.spring.demo2.InvocationHandler;" +  rt+
        "public class $Proxy0 implements " + infce.getName() + " {" + rt +
        "   public $Proxy0(InvocationHandler h) {" + rt +
        "       this.h = h;" + rt +
        "   }" + rt +
        "  private InvocationHandler h;" + rt+ 
        methodStr + rt +
        "}" ;
        //产生代理类的java文件
        String filename = System.getProperty("user.dir") +"/bin/com/zs/spring/demo2/$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("com.zs.spring.demo2.$Proxy0");

        Constructor ctr = c.getConstructor(InvocationHandler.class);
        return ctr.newInstance(h);
    }
}

创建我们的测试类

package com.zs.spring.demo2;

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();

}

}

你可能感兴趣的:(java)