设计模式之代理模式(2)
前一篇文章提到了是静态代理,其实用聚合的方式实现代理,当需求过多的时候,也会发生类爆发。
所以上有政策,下有对策嘛!可以把所有的代理放在一个代理类中Proxy类中,Proxy被称为总代理!由总代理实现动态代理!
要说的东西有点多,先上个代码把!
Proxy.java(总代理)
package cn.asto.proxy; import java.io.FileWriter; import java.lang.reflect.Constructor; import java.net.URL; import java.net.URLClassLoader; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class Proxy { public static Moveable getProxyInstance() throws Exception{ String rt ="\r\t"; String str = "package cn.asto.proxy;"+ rt + "public class TankTimeProxy implements Moveable {"+ rt + " private Moveable t;"+ rt + " public TankTimeProxy(Moveable t) {"+ rt + " super();"+ rt + " this.t = t;"+ rt + "}"+ rt + " @Override"+ rt + " public void move() {"+ rt + " long startTime = System.currentTimeMillis();"+ rt + " System.out.println(\"startTime:\"+startTime);"+ rt + " t.move();"+ rt + " long endTime = System.currentTimeMillis();"+ rt + " System.out.println(\"Time:\"+(endTime-startTime));"+ rt + " }"+ rt + "}"; String fileName =System.getProperty("user.dir")+"/src/cn/asto/proxy/TankTimeProxy.java"; FileWriter fw = new FileWriter(fileName); fw.write(str); fw.flush(); fw.close(); //compile 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("cn.asto.proxy.TankTimeProxy"); System.out.println(c); Constructor ctr = c.getConstructor(Moveable.class); Moveable m = (Moveable)ctr.newInstance(new Tank()); return m; } }
Test1.java
package cn.asto.compiler.test; import cn.asto.proxy.Moveable; import cn.asto.proxy.Proxy; public class Test1 { public static void main(String args[]) throws Exception{ Moveable m = Proxy.getProxyInstance(); m.move(); } }
我的目录结构:
下面开始我的BB:
动态代理解决了静态代理的类爆炸问题,因为不需要写代理类,代理类动态生成。
先将str通过字符流写入文件,再通过jdk自带的工具进行编译,加载到jvm里面,然后利用java的反射机制生成对象。
本质上来说,其实就是通过动态加载类,减少了静态代理类的编写。就这么简单!
好,我的BB结束了!