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结束了!

  • 相关阅读:
    SourceForge上发布dedup util 收藏
    IBM快速整合Diligent 触动了谁的神经?
    Data Domain揭开其神秘面纱 加速中国业务发展
    Java NIO原理和使用
    用PDB库调试Python程序
    windows下配置eclipse + Python + PyDev + tornado,并使用pylint进行静态检测
    函数fork与vfork的区别与联系详解
    关于C++中友元类和友元函数的示例讲解
    const成员函数
    pthread_cond_wait()深入解析
  • 原文地址:https://www.cnblogs.com/think-in-java/p/4737408.html
Copyright © 2011-2022 走看看