• 动态代理动态生成java文件并编译成class文件


    刚看到的这个,太生猛了...以前学动态代理还知其然,不知其所以然的...现在算是有点了解了...
    
    主要是动态编译这点比较有趣,
    
    1 定义一个接口,只有一个方法,sell  (为什么要定义这个接口,就不多说了..面向接口编程可以说是必须的)
    
    package com.cjb.proxy;
    /**
     *   类说明
     *   表示商店
     *   @creator 陈静波
     *   @email 
     *   @create-time  May 20, 2010 9:43:40 AM   
     */
    public interface Store
    {
     public void sell();
    }
    
    2 定义一个实现类,在这里, 这个类就是被代理类..我们需要为这个类产生一个代理.
    
    package com.cjb.proxy;
    /**
     *   类说明
     *   @creator 陈静波
     *   @email 
     *   @create-time  May 20, 2010 9:54:48 AM   
     */
    public class Supermarket implements Store
    {
     
     @Override
     public void sell()
     {
      System.out.println("sel in supermarket.....");
     }
     
    }
    
    3 下面是测试类.我们在这个类里动态的生成了一个代理类Dealer.java ,然后动态的编译这个类,最后调用这个类的方法.
    
    package com.cjb.proxy;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.lang.reflect.Constructor;
    import java.net.URL;
    import java.net.URLClassLoader;
    
    import javax.tools.JavaCompiler;
    import javax.tools.StandardJavaFileManager;
    import javax.tools.ToolProvider;
    import javax.tools.JavaCompiler.CompilationTask;
    
    /**
     * 类说明
     * 
     * @creator 陈静波
     * @email 
     * @create-time May 20, 2010 10:11:29 AM
     */
    public class Test
    {
     public static void main(String[] args) throws Exception
     {
      String rt = "\r\n";
      String source = "package com.cjb.proxy;" + "/**" + " *   类说明"+ rt 
        + "*   @creator 陈静波" + " *   @email "+ rt 
        + " *   @create-time  May 20, 2010 10:05:23 AM   " + " */"+ rt 
        + "public class Dealer implements Store"+ rt  + "{"+ rt  + "private Store s;" + rt +
        "public Dealer(Store s)"+ rt  + " {" + "  this.s = s;"+ rt 
        + " }" + rt +
    
        " public void sell()" + " {"+ rt 
        + "  System.out.println(\"price markup....\");"+ rt 
        + "  s.sell();" + " }" + rt+ 
        "}";
    
      String fileName = System.getProperty("user.dir")//获取到项目的根路径
        + "/src/com/cjb/proxy/Dealer.java";
      File f = new File(fileName);
      FileWriter fw = new FileWriter(f);
      fw.write(source);
      fw.flush();
      fw.close();//这里只是产生一个JAVA文件,简单的IO操作
    
      // compile下面开始编译这个Store.java
      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("com.cjb.proxy.Dealer");
      System.out.println(c);
    
    //客户端调用
    
      Constructor ctr = c.getConstructor(Store.class);
      Store s = (Store)ctr.newInstance(new Supermarket());//这里看到,这个我们这个代理类必须实现Store的原因
      s.sell();
     }
    }
    
    总结下
    
    这节的内容说的是动态的产生java文件并编译它..其实,说起来,我们直接写一个java文件会方便很多,因为其实我们的代码都在字符串source中的,但是,为什么还要这样费事的动态去产生,主要目的就是让项目少一个类.少一个JAVA文件.还有一个目的,可以看到,我们动态产生的这个类,在最后调用的时候,我们是不需要知道他的类名的.重要点在于动态.看懂了这个下面的动态代理才能知道根本

  • 相关阅读:
    jsp设置footer底部内容
    dashboard项目心得:
    深度和广度优先算法
    一个action读取另一个action里的session
    算法笔记-0302
    JAVA基础---面向对象
    Flutter 读写本地文件
    Dart 处理json,built_value库
    Flutter 页面入栈和出栈
    web项目如何使用Material Icons
  • 原文地址:https://www.cnblogs.com/daichangya/p/12960016.html
Copyright © 2020-2023  润新知