动态代理---动态生成java文件并编译成class文件

字体大小: 中小 标准 ->行高大小: 标准

主要是动态编译这点比较有趣,

1 定义一个接口,只有一个方法,sell  (为什么要定义这个接口,就不多说了..面向接口编程可以说是必须的)

1
2
3
4
5
6
package com.cjb.proxy;
 public interface Store
{
 public void sell();
}

2 定义一个实现类,在这里, 这个类就是被代理类..我们需要为这个类产生一个代理.

1
2
3
4
5
6
7
8
9
10
11
12
package com.cjb.proxy;
 public class Supermarket implements Store
{
   
 @Override
 public void sell()
 {
  System.out.println("sel in supermarket.....");
 }
   
}

3 下面是测试类.我们在这个类里动态的生成了一个代理类Dealer.java ,然后动态的编译这个类,最后调用这个类的方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.cjb.proxy;
 import java.io.File; import java.io.FileWriter; import java.lang.reflect.Constructor; import java.net.URL; import java.net.URLClassLoader;
 import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import javax.tools.JavaCompiler.CompilationTask;
  
 public class Test
{
 public static void main(String[] args) throws Exception
 {
  String rt = "\r\n";
  String source = "package com.cjb.proxy;" + ""+ rt
    + "public class Dealer implements Store"+ rt  + "{"+ rt  + "private Store s;" + rt +
    "public Dealer(Store s)"+ rt  + " {" + "  this.s = s;"+ rt
    + " }" + rt +
  
    " public void sell()" + " {"+ rt
    + "  System.out.println(\"price markup....\");"+ rt
    + "  s.sell();" + " }" + rt+
    "}";
  
  String fileName = System.getProperty("user.dir")//获取到项目的根路径     + "/src/com/cjb/proxy/Dealer.java";
  File f = new File(fileName);
  FileWriter fw = new FileWriter(f);
  fw.write(source);
  fw.flush();
  fw.close();//这里只是产生一个JAVA文件,简单的IO操作
  // compile下面开始编译这个Store.java   JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null,
    null, null);
  Iterable units = fileMgr.getJavaFileObjects(fileName);
  CompilationTask t = compiler.getTask(null, fileMgr, null, null, null,
    units);
  t.call();
  fileMgr.close();
  
  // load into memory and create an instance   URL[] urls = new URL[] { new URL("file:/"
    + System.getProperty("user.dir") + "/src") };
  URLClassLoader ul = new URLClassLoader(urls);
  Class c = ul.loadClass("com.cjb.proxy.Dealer");
  System.out.println(c);
 //客户端调用
  Constructor ctr = c.getConstructor(Store.class);
  Store s = (Store)ctr.newInstance(new Supermarket());//这里看到,这个我们这个代理类必须实现Store的原因   s.sell();
 }
}

总结下

这节的内容说的是动态的产生java文件并编译它..其实,说起来,我们直接写一个java文件会方便很多,因为其实我们的代码都在字符串source中的,但是,为什么还要这样费事的动态去产生,主要目的就是让项目少一个类.少一个JAVA文件.还有一个目的,可以看到,我们动态产生的这个类,在最后调用的时候,我们是不需要知道他的类名的.重要点在于动态.看懂了这个下面的动态代理才能知道根本

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/70203.html