• JDK动态代理实现原理


    JDK动态代理实现原理思路:

    1. 声明一段源码,这段源码动态生成我们的动态代理;

    //1、声明一段源码,动态产生代理
    //windows系统中的回车换行符
    
    String rt = "
    ";
    String methodStr="";
    for(Method m : infce.getMethods()) {
        methodStr += "    @Override"+rt+
        " public void " + m.getName() +"() {"++
        " try{"+rt+
        " Method md = "+infce.getName+".class.getMethod(""+m.getName()+"""+rt+
        " h.invoke(this,md);"+rt+
        " }catch(Exception e){e.printStackTra();}"+rt+
    "}";
    }
    
    String str=
    "package com.imooc.proxy;"+rt+
    "import java.lang.reflect.Method;"+rt+
    "import com.imooc.proxy.InvocationHandler+rt+
    "public class $Proxy0 implements+infce.getName()+ " {"+rt+
    "    public $Proxy0(InvocationHandler h) +rt+
    "    this.h = h;"+rt+
    "}"+rt+
    " private InvocationHandler h;"+rt+
    methodStr+rt+
    "}";
    

    2. 把源码生成Java文件;

    //产生代理类的Java文件
    String filename = System.getProperty("user.dir")+"/bin/com/imooc/proxy/$Proxy0.java";
    File file = new File(filename);
    FileUtils.writeStringToFile(file, str);
    

    3. 获取系统的Java编译器(JavaCompiler类似与javac);

    JavaCompiler comproiler = ToolProvider.getSystemJavaCompiler();
    

    4. 获取文件管理器StandardJavaFileManager;

    StandardJavaFileManager fileManager = comproiler.getStandardFileManager(null, null, null);
    

    5. 获取需要编译的java文件对象(Iterable);

    Iterable units = fileManager.getJavaFileObjects(file);
    

    6. 获取编译的任务();

    CompilationTask task = comproiler.getTask(null, fileManager, null, null, null, units);
    

    7. 进行编译;

    task.call();
    

    8. 关闭文件管理器

    fileManager.close();
    

    9. 编译完成后会生成class文件;

    10. 把class文件加载到内存中;

    //因为生成的文件在bin目录下,可以直接使用ClassLoader进行加载
    ClassLoader cl = ClassLoader.getSystemClassLoader();
    //默认生成的代理类名称均为 $Proxy0
    Class c = cl.loadClass("com.imooc.proxy.$Proxy0");
    

    11. 产生一个代理类的对象,并返回该对象;

    //获取类的构造函数,创建类的实例
    Constructor ctr = c.getConstructor(InvocationHandler.class);
    return ctr.newInstance(h);
    

    12. 代理类的调用

    创建一个InvocationHandler(专门做事务处理)

    Car car = new Car();
    InvocationHandler h = new TimeHandler(car);
    Moveable m = (Moveable) Proxy.newProxyInstance(Moveable.class,h);
    m.move();
    
  • 相关阅读:
    简单测试AF3.0.4
    好玩的Mac键盘
    黑盒测试和白盒测试
    iOS开发之原生二维码生成与扫描
    Swift
    JavaScript null and undefined
    java防止表单重复提交
    Java http post
    Redhat 6.5 x64 下载地址
    Spring 官方下载地址(非Maven)
  • 原文地址:https://www.cnblogs.com/muscleape/p/9043896.html
Copyright © 2020-2023  润新知