我们假设被代理的对象实现了一个接口,不管它实现了什么样的接口,但是它实现了一个接口,用集成也可以实现代理,但是继承不好,所以我们被代理的类要实现一个接口,这个在Spring也是这么要求的,不过Spring也提供了另外一种方式,你可以不实现接口,也能给你做成一个代理,这是Spring不推荐的,Spring能实现但是不推荐这样用AOP是动态代理的一种应用,我们可以用任何的对象任何的类,我怎么样给他生成这个代理呢,为了模拟JDK的实现,这个类叫做Proxy.
package com.learn.proxy;import java.io.File;
import java.io.FileWriter;
import java.io.IOException;import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;/*** 至少你要知道可以动态的生成类的* 你生成类还不行,你还需要load到内存* load到内存然后在生成他的一个对象,这个时候就需要用到反射了* @author Leon.Sun**/
public class Test1 {public static void main(String[] args) throws IOException {String rt = "\r\n";String src = "package com.learn.proxy;" +"public class TankTimeProxy implements Moveable {" + rt +"public TankTimeProxy(Moveable t) {" + rt +"super();" + rt +"this.t = t;" + rt +"}" + rt +"Moveable t;" + rt +"@Override " + rt +"public void move() {" + rt +"long start = System.currentTimeMillis();" + rt +"System.out.println(\"starttime:\" + start);" + rt +"t.move();" + rt +"long end = System.currentTimeMillis();" + rt +"System.out.println(\"time:\" + (end-start));" + rt +"}" + rt + "}";// System.out.println(System.getProperty("user.dir"));String fileName = System.getProperty("user.dir") + "/src/com/learn/proxy/TankTimeProxy.java";File f = new File(fileName);FileWriter fw = new FileWriter(f);fw.write(src);fw.flush();fw.close();/*** 这两个类来自javax.tools包,在API文档里面有* 这句话相当于我们拿到编译器了,可是SUN对于编译器的设计呢,很不直观,* 首先我们拿到编译对象*/JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();/*** com.sun.tools.javac.api.JavacTool, JDK自带的*/// System.out.println(compiler.getClass().getName());/*** 首先需要一个FileManager,File的管理者* 这里里面有三个参数* diagnosticListener诊断的监听器,就是你编译的期间有什么错误,由他来监听和收集* locale就是和国际化相关的,charset和国际化相关的,我们直接写null* 就会使用默认的语言JDK,拿到这个FileManager之后呢* * 做一个FileManager,这个FileManager管理着我们的这些文件*/StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);/*** 根据文件的名字他就可以拿到一系列的JavaFile,注意它是getJavaFileObjects,* 也就是你里面可以写多个名字,也就是现在通过FileManager,我可以找到这个文件了* 把这个对象放到Iterable对象里面,Iterable简单的理解就是一个数组就完了,* 可以用它来进行迭代* * 这个文件就是动态生成的文件*/Iterable units = fileManager.getJavaFileObjects(fileName);/*** 一次编译任务可以编译好多文件* out 你给他输出到哪里去 这个我们不管 写null* 第二个参数是FileManager是谁,因为你编译的时候要通过FileManager来找文件* diagnosticListener 第三个是监听器,* options你编译的时候指定的参数 先写null* classes 是null不管,就是你用到的class文件* units 是我们要编译哪些文件* 这个接口用起来很复杂,今天这个东西并不是我们的重点,* 总而言之我们通过这个方法getTask可以拿到CompilationTask,* 也就是编译的任务,我终于可以让他编译了* * 接下来我们根据FileManager我们编译的内容,我们生成一个CompilationTask* */CompilationTask t = compiler.getTask(null, fileManager, null, null, null, units);/*** 有了这个任务以后,我们call()调用这个任务就能完成了* * 调用call就编译一大堆的内容*/t.call();/*** 能不能编译完成呢*/fileManager.close();}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!