使用java的JavaCompiler模拟Proxy自动编译

来源:互联网 发布:sql select嵌套查询 编辑:程序博客网 时间:2024/05/06 00:08

使用java的jdk6的JavaCompiler进行自动编译,将一段字符串编译为class文件、并且存到内存中,可以对任意的对象实现代理

比方说有一个对象Tank要做代理,就先创建一个TimeHandler来实现InvocationHandler,该TimeHadler中保存了一个该对象的引用

import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class TimeHandler implements InvocationHandler{Object target;public TimeHandler(Object target) {this.target = target;}public void invoke(Object o,Method m) {//是对哪个对象调用Method m,m为二进制代码,前面的o指的是代理的那个long start = System.currentTimeMillis();try {m.invoke(target);//调用target这个对象的m方法。第二个指的是想方法中传的参数,本例为空} catch (Exception e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println("time:"+(end-start));}}
客户端调用:

public class Client {public static void main(String[] args) throws Exception {Tank t = new Tank();InvocationHandler ich = new TimeHandler(t);Moveable m = (Moveable)Proxy.newProxyInstance(Moveable.class,ich);m.move();}}




package com.lxp.proxy;import java.io.File;import java.io.FileWriter;import java.io.IOException;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 Proxy {public static Object newProxyInstance(Class inface,InvocationHandler h) throws Exception {String rt = "\r\n";String src = "package com.lxp.proxy;"+rt+"public class TankTimeProxy implements " +inface.getName()+"{"+rt+"Moveable t;"+rt+"TankTimeProxy(Moveable t) {"+rt+"this.t = t;"+rt+"}"+rt+"public void move() {"+rt+"long start = System.currentTimeMillis();"+rt+"t.move();"+rt+"long end = System.currentTimeMillis();"+rt+"System.out.println(\"time:\"+(end-start));"+rt+"}"+rt+"}";String fileName = System.getProperty("user.dir")+"/src/com/lxp/proxy/TankTimeProxy.java";File f = new File(fileName);FileWriter fw = new FileWriter(f);fw.write(src);fw.flush();fw.close();//使用java自带的编译工具JavaCompiler对一段字符串进行编译JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();//拿到系统编译器javac//System.out.println(compiler.getClass().getName());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 instanceURL[] urls = new URL[]{new URL("file:/"+System.getProperty("user.dir")+"/src")};URLClassLoader ul = new URLClassLoader(urls);Class c = ul.loadClass("com.lxp.proxy.TankTimeProxy");//生成class到内存//System.out.println(c);Constructor ctr = c.getConstructor(Moveable.class);//寻找一个有参数的并且参数类型是Moveable的构造方法Moveable m = (Moveable) ctr.newInstance(new Tank());//构造方法中有参数,所以穿一个值过去m.move();return null;}}




0 0
原创粉丝点击