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文件.还有一个目的,可以看到,我们动态产生的这个类,在最后调用的时候,我们是不需要知道他的类名的.重要点在于动态.看懂了这个下面的动态代理才能知道根本