模拟JDK动态代理

接口Moveable:

public interface Moveable {
 public void move();
 public void stop();
}
接口的实现类Tank:
public class Tank implements Moveable{
        public void move() {
       System.out.println("tank is moving...");
       try {
           Thread.sleep(new Random().nextInt(10000));
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
    }
    @Override
    public void stop() {
       System.out.println("tank stoped...");
    }

}

模拟的InvocationHandler:
public interface InvocationHandler {
    public void invoke(Object object,Method method);

}

InvocationHandler的实现,也即应用类LogHandler:
public class LogHandler implements InvocationHandler{
    private Object target;//被代理对象
    public LogHandler(Object object) {
       super();
       this.target = object;
    }
    @Override
    public void invoke(Object object,Method method) {
       //先调用自己的逻辑,然后调用被代理对象的方法,最后再调用自己的逻辑
       System.out.println("log begin...");
       try {
           method.invoke(target);
       } catch (Exception e) {
           e.printStackTrace();
       }
       System.out.println("log end...");
    }

}

本文中最重要的代理类Proxy:
public class Proxy {
    public static Object newProxyInstance(Class interClass,InvocationHandler handler) throws Exception{
       String srcString="";//源代码字符串
       String rt = "\r\n";//回车换行符
       String methodString = "";//方法字符串
       Method[] methods = interClass.getMethods();//找出接口interClass中的所有方法
       for(Method method:methods){
           //将接口中的所有方法拼接为方法字符串
           methodString += 
                     "   public void " + method.getName() +"(){" + rt +//方法头部
                     "   try{" + rt +
                     "      Method md = " +interClass.getName() +".class.getMethod(\"" + method.getName() +"\");" + rt +//获得接口中的一个方法
                     "      handler.invoke(this,md);" + rt +//用处理器handler进行处理
                     "   }catch(Exception e){" + rt +
                     "      e.printStackTrace();" + rt +
                     "   }" + rt +
                     "   }" + rt ;
       }
       srcString = "package com.hibernate.proxy;" + rt +
                  "import java.lang.reflect.Method;" + rt +
                  "public class $Proxy1 implements "+ interClass.getName() + "{" + rt +//此处应注意:@Proxy1一定要记得实现传过来的接口
                  "   private InvocationHandler handler;" + rt +//代理中应该保存一个处理器handler,并在构造函数中进行传递
                  "   public $Proxy1(InvocationHandler handler){" +rt +
                  "      this.handler = handler;" + rt +
                  "   }" + rt +
                  methodString + rt +
                  "}";
       String fileName = System.getProperty("user.dir")+"/src/com/hibernate/proxy/$Proxy1.java";//这个是文件的名称
       File file = new File(fileName);//新建文件
       if(!file.exists()){
           file.createNewFile();
       }
       FileWriter writer = new FileWriter(file);
       writer.write(srcString);//将源代码写到文件中
       writer.flush();
       writer.close();
       //以下的部分是对刚才新建的源代码文件尽心编译
       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
       StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
       Iterable units = manager.getJavaFileObjects(fileName);
       CompilationTask task = compiler.getTask(null, manager, null, null, null, units);
       task.call();
       manager.close();
       //将编译后的文件加载到内存
       URL[] urls = new URL[]{new URL("file:/" + System.getProperty("user.dir"+"/src"))};
       URLClassLoader classLoader = new URLClassLoader(urls);
       Class class1 = classLoader.loadClass("com.hibernate.proxy.$Proxy1");
       //生成新的对象
       //获得代理对象$proxy1的构造方法,并将参数的类型传给它
       Constructor constructor = class1.getConstructor(InvocationHandler.class);
       //构造一个新的代理对象,参数为传进来的handler
       Object object = (Object)constructor.newInstance(handler);
       //返回新生成的代理对象
       return object;
    }

}

测试类:
public class ProxyTest {
    public static void main(String[] args) {
       Tank tank = new Tank();
       InvocationHandler handler = new LogHandler(tank);
       try {
           Moveable moveable = (Moveable)Proxy.newProxyInstance(Moveable.class, handler);//生成一个和被代理对象具有相同接口的代理对象
           moveable.move();
           moveable.stop();
       } catch (Exception e) {
           e.printStackTrace();
       }
    }

}

编译生成的$Proxy1类:
package com.hibernate.proxy;
import java.lang.reflect.Method;
public class $Proxy1 implements com.hibernate.proxy.Moveable{
    private InvocationHandler handler;
    public $Proxy1(InvocationHandler handler){
       this.handler = handler;
    }
    public void stop(){
    try{
       Method md = com.hibernate.proxy.Moveable.class.getMethod("stop");
       handler.invoke(this,md);
    }catch(Exception e){
       e.printStackTrace();
    }
    }
    public void move(){
    try{
       Method md = com.hibernate.proxy.Moveable.class.getMethod("move");
       handler.invoke(this,md);
    }catch(Exception e){
       e.printStackTrace();
    }
    }
 

}

 

你可能感兴趣的:(JDK动态代理)