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

  • 相关阅读:
    华章IT图书书讯(2011年第8期)
    iPhone游戏开发实践指南
    【北京讲座】Android系统Framework层源码分析(2011.09.24)
    深入理解Android
    你学或不学,Java就在那里,不离不弃
    近百本精品图书全部免费赠送——仅面向学生
    极限编程(Extreme Programming, XP)
    对任何希望深入理解C#的程序员来说,这本书都是不容错过的经典书籍
    C# 文件操作(转)
    一些数据格式化Eval( " ")和DataBinder.Eval(Container.DataItem, " ")的区别及用法
  • 原文地址:https://www.cnblogs.com/think-in-java/p/4737408.html
Copyright © 2011-2022 走看看