标签:
这次我们要实现的是对任意接口,任意的方法进行特定的代理
这里不一样的只有Proxy类,要实现对所有方法进行代理,那么重点就在于获得接口的所有方法
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
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 ProxyG2 {
//产生新的动态代理类
public static Object newProxyInstance(Class intf) throws Exception{ //将接口当成参数传入,这样就可以代理实现了任意接口的类,而不仅是实现了Moveable接口
String methodsString = ""; //获得所有方法字符串
String rt = "\r\n";
Method[] methods = intf.getMethods();
for(Method m : methods){
methodsString += "@Override "+ rt+
"public void "+m.getName()+" (){"+"" +rt+
" long start = System.currentTimeMillis();"+rt+
" System.out.println(\"start time is \"+start);"+rt+
" t."+m.getName()+"();"+rt+
" long end = System.currentTimeMillis();"+rt+
" System.out.println(\"end time is \"+end);"+rt+
" System.out.println(\"time is \"+(end - start));"+rt+
"}"+rt;
}
//将一下字符串动态编译,生成代理类
//实现方式有以下击中:jdk6.0 complier API;CGLib; ASM
String src =
"public class TankTimeProxy implements " +intf.getName()+ "{"+rt+ //直接用intf,是调用toString方法,前会加入字符串 interface
" Moveable t;"+rt+
" public TankTimeProxy("+intf.getName()+" t) {"+rt+
" this.t = t;"+rt+
" }"+rt+
methodsString+
"}";
//进行编译
String fileName = "g:/src/TankTimeProxy.java";//放在指定的地方
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
//System.out.println(fileName);
fw.write(src); //写入内容
fw.flush();
fw.close();
//进行编译
//首先获得编译器
//compiler 为java编译器 javac
//获得编译器对象
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//System.out.println(compiler.getClass().getName());//取得类名
//参数含义 (编译诊断,locale,charset)
//管理动态生成d文件
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);//默认值
//根据参数获取多个java文件 返回java文件对象
Iterable units = fileManager.getJavaFileObjects(fileName);
//“编译任务”对象
JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);
task.call();//调用
fileManager.close();
//System.out.println("***************************************");
//************以上过程获得了java文件源码,编译生成了java文件的class文件*******
//加载至内存,生成新对象
//Class.load(0 是加载path路径的class文件
//URLClassLoader是将硬盘中的class文件加载进入
//通过Url引入本地文件
URL[] urls = new URL[]{new URL("file:/"+"g:/src/")}; //访问本地文件 指定class文件存放的位置
//去指定路径寻找class文件
URLClassLoader urlClassLoader = new URLClassLoader(urls);
Class c = urlClassLoader.loadClass("TankTimeProxy");
System.out.println(c);
//执行
//c.newInstance(); 是调用空的构造方法
//获得构造方法
//根据java虚拟机,每一个构造方法也相当于一个对象
Constructor constructor = c.getConstructor(intf);
//产生新对象
Object m = constructor.newInstance(new Tank()); //new Tank()为构造方法的参数 即被代理对象
//m.move();
return m;
}
}
标签:
原文地址:http://www.cnblogs.com/chentao-cus/p/4817174.html