zoukankan      html  css  js  c++  java
  • 设计模式之代理模式(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 ="
    	";
            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结束了!

  • 相关阅读:
    indexDB的用法
    append动态生成的元素,无法触发事件的原因及解决方案
    jquery中attr()和prop()的区别
    arguments.callee
    meter标签度量衡如何改变颜色
    Nginx入门
    linux中的权限管理
    python_面向对象
    ORM
    Flask入门
  • 原文地址:https://www.cnblogs.com/think-in-java/p/4737408.html
Copyright © 2011-2022 走看看