深度模拟java动态代理实现机制系类之二

这次我们要实现的是对任意接口,任意的方法进行特定的代理

这里不一样的只有Proxy类,要实现对所有方法进行代理,那么重点就在于获得接口的所有方法

  1 import java.io.File;
  2 import java.io.FileWriter;
  3 import java.lang.reflect.Constructor;
  4 import java.lang.reflect.Method;
  5 import java.net.URL;
  6 import java.net.URLClassLoader;
  7 
  8 import javax.tools.JavaCompiler;
  9 import javax.tools.StandardJavaFileManager;
 10 import javax.tools.ToolProvider;
 11 import javax.tools.JavaCompiler.CompilationTask;
 12 
 13 //该类实现了对任意接口,任意方法的特定代理
 14 public class ProxyG2 {
 15     //产生新的动态代理类
 16     public static Object newProxyInstance(Class intf) throws Exception{  //将接口当成参数传入,这样就可以代理实现了任意接口的类,而不仅是实现了Moveable接口
 17         String methodsString = "";  //获得所有方法字符串
 18         String rt = "\r\n";
 19 
 20         Method[] methods = intf.getMethods();
 21         for(Method m : methods){
 22             methodsString += "@Override "+ rt+
 23                     "public void "+m.getName()+" (){"+"" +rt+
 24                     "        long start = System.currentTimeMillis();"+rt+
 25                     "        System.out.println(\"start time is \"+start);"+rt+
 26                     "        t."+m.getName()+"();"+rt+
 27                     "        long end = System.currentTimeMillis();"+rt+
 28                     "        System.out.println(\"end time is \"+end);"+rt+
 29                     "        System.out.println(\"time is \"+(end - start));"+rt+
 30                     "}"+rt;
 31         }
 32 
 33 
 34         //将一下字符串动态编译,生成代理类
 35         //实现方式有以下击中:jdk6.0 complier API;CGLib;  ASM
 36 
 37         String src =
 38                 "public class TankTimeProxy implements " +intf.getName()+ "{"+rt+   //直接用intf,是调用toString方法,前会加入字符串 interface
 39                         "    Moveable t;"+rt+
 40 
 41                         "    public TankTimeProxy("+intf.getName()+" t) {"+rt+
 42                         "    this.t = t;"+rt+
 43                         "    }"+rt+
 44 
 45                         methodsString+
 46                         "}";
 47 
 48         //进行编译
 49         String fileName = "g:/src/TankTimeProxy.java";//放在指定的地方
 50         File f = new File(fileName);
 51         FileWriter fw = new FileWriter(f);
 52         //System.out.println(fileName);
 53         fw.write(src);  //写入内容
 54 
 55         fw.flush();
 56         fw.close();
 57 
 58         //进行编译
 59         //首先获得编译器
 60         //compiler  为java编译器    javac
 61         //获得编译器对象
 62         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
 63         //System.out.println(compiler.getClass().getName());//取得类名
 64         //参数含义 (编译诊断,locale,charset)
 65         //管理动态生成d文件
 66         StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);//默认值
 67         //根据参数获取多个java文件   返回java文件对象
 68         Iterable units = fileManager.getJavaFileObjects(fileName);
 69 
 70         //“编译任务”对象
 71         JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);
 72         task.call();//调用
 73         fileManager.close();
 74         //System.out.println("***************************************");
 75 
 76         //************以上过程获得了java文件源码,编译生成了java文件的class文件*******
 77         //加载至内存,生成新对象
 78         //Class.load(0 是加载path路径的class文件
 79         //URLClassLoader是将硬盘中的class文件加载进入
 80 
 81         //通过Url引入本地文件
 82         URL[] urls = new URL[]{new URL("file:/"+"g:/src/")}; //访问本地文件   指定class文件存放的位置
 83         //去指定路径寻找class文件
 84         URLClassLoader urlClassLoader = new URLClassLoader(urls);
 85 
 86         Class c = urlClassLoader.loadClass("TankTimeProxy");
 87 
 88         System.out.println(c);
 89 
 90         //执行
 91         //c.newInstance(); 是调用空的构造方法
 92 
 93         //获得构造方法
 94         //根据java虚拟机,每一个构造方法也相当于一个对象
 95         Constructor constructor = c.getConstructor(intf);
 96 
 97         //产生新对象
 98         Object m =  constructor.newInstance(new Tank());  //new Tank()为构造方法的参数   即被代理对象
 99 
100         //m.move();
101 
102         return m;
103     }
104 }

 

posted @ 2015-09-17 18:01  苏幕遮soft  阅读(277)  评论(0编辑  收藏  举报