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

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

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编译器  即javac
37         //获得编译器对象
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、执行结果

posted @ 2015-09-16 22:29  苏幕遮soft  阅读(712)  评论(0编辑  收藏  举报