首页 > 学院 > 开发设计 > 正文

简单模拟java动态动态代理机制的底层实现原理

2019-11-14 15:37:22
字体:
来源:转载
供稿:网友

在网上学习了马士兵老师的设计模式视屏,过程中也有认真的做相应的笔记。在次分享我的一些
成果,方便大家的进一步学习。

1、接口
 1 public interface Moveable { 2 void move(); 3 } 

2、被代理的对象

 1 public class Tank implements Moveable { 2  3     @Override 4     public void move() { 5          6         System.out.PRintln("Tank Moving..."); 7         try { 8             Thread.sleep(new Random().nextInt(10000)); 9         } catch (InterruptedException e) {10             e.printStackTrace();11         }12         13     }14     15 }

 



3、测试主类

 1 public class Test { 2     public static void main(String[] args) throws Exception{ 3         String rt = "/r/n"; 4  5     //代理类的字符串代码 6         String src = 7                 "public class TankTimeProxy implements Moveable {"+rt+ 8                 "    Moveable t;"+rt+ 9 10                 "    public TankTimeProxy(Moveable t) {"+rt+11                 "    this.t = t;"+rt+12                 "    }"+rt+13 14                 "    @Override"+rt+15                 "    public void move() {"+rt+16                 "        long start = System.currentTimeMillis();"+rt+17                 "        System.out.println(/"start time is /"+start);"+rt+18                 "        t.move();"+rt+19                 "        long end = System.currentTimeMillis();"+rt+20                 "        System.out.println(/"end time is /"+end);"+rt+21                 "        System.out.println(/"time is /"+(end - start));"+rt+22                 "    }"+rt+23                 "}";24 25         //将字符串写入java文件********************************************************************************26         String fileName = System.getProperty("user.dir")+"/src/TankTimeProxy.java";//放置在(根目录+文件名)下27         File f = new File(fileName);28         FileWriter fw = new FileWriter(f);29      //写入内容30         fw.write(src);  31         fw.flush();32         fw.close();33 34         //进行编译********************************************************************************************35         //首先获得编译器36         //compiler 为java编译器  即javac37         //获得编译器对象38         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();39 40         //参数含义 (编译诊断,locale,charset)41         //管理动态生成的文件的StandardJavaFileManager对象42         StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);//默认值43 44         //根据参数获取多个java文件   返回java文件对象集45         Iterable units = fileManager.getJavaFileObjects(fileName);46 47        //“编译任务”对象48         JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);49         task.call();//调用50         fileManager.close();51 52         //************以上过程获得了java文件源码,编译java文件生成了相对应的class文件****************53 54         //***************以下过程为将class文件加载至内存,生成新对象*****************************55         //Class.load() 是加载path路径的class文件56         //URLClassLoader是将硬盘中的class文件加载进入57 58         //通过Url引入本地文件59         URL[] urls = new URL[]{new URL("file:/"+System.getProperty("user.dir")+"/out/production/proxy")}; //访问本地class文件,这里我用的是IntellijIDEA,默认   生成的class文件的目录在  /out/production/  下60 61 62         //去指定路径寻找class文件63         URLClassLoader urlClassLoader = new URLClassLoader(urls);64 65         Class c = urlClassLoader.loadClass("TankTimeProxy");66 67         System.out.println(c);68 69         //执行70         //c.newInstance(); 是调用空的构造方法71 72         //获得构造方法73         //根据java虚拟机,每一个构造方法也相当于一个对象74         Constructor constructor = c.getConstructor(Moveable.class);75 76         //产生新对象77         Moveable m = (Moveable) constructor.newInstance(new Tank());  //new Tank()为构造方法的参数   即被代理对象78 79         m.move();80 81     }82 }83 84  

 

4、执行结果


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表