zoukankan      html  css  js  c++  java
  • JDK动态代理之跳过动态代理徒手编写动态代理

    我的这篇博客分析了动态代理对象是如何生成的 java动态代理之JDK源码解析

    JDK动态代理的对象是JDK在没有产生任何文件的条件下,JVM直接通过字节数组生成的对象。

    可是这种模式我们是没办法复制的。

    你可能是一个非常牛逼的高手,能够直接编写存放字节码文件的字节数组;然而没有一个地方让你能够直接将这个数组载入虚拟机。

    如果我们需要编写一个动态的代理对象,只能一步一步的调用jdk提供的接口方法。

    步骤大致是这样的:创建接口文件==》动态生成java文件内容==》程序创建java文件==》调用Java编译功能==>载入虚拟机==》利用反射生成代理对象

    接口文件IPeople:

    package c.b;
    
    public interface IPeople {
        void say();
    }

    动态生成java文件内容

     public static String createContent(){
            final String ln="
    ";
            StringBuilder sb=new StringBuilder();
            sb.append("package c.b;"+ln);
            sb.append("public class People implements IPeople { "+ln);
            sb.append("@Override"+ln);
            sb.append("public void say() {"+ln);
            sb.append("System.out.println("say......");"+ln);
            sb.append("}"+ln);
            sb.append("}"+ln);
            return sb.toString();
        };

    程序创建java文件

    public static File createfile(String src) throws IOException {
            String filePath=MyProxy.class.getResource("").getPath();
            File f=new File(filePath+"People.java");
            FileWriter fw=new FileWriter(f);
            fw.write(src);
            fw.flush();
            fw.close();
            return f;
        }

    调用Java编译功能

     public static void compier(File f) throws IOException {
            JavaCompiler compier= ToolProvider.getSystemJavaCompiler();
            StandardJavaFileManager manage=compier.getStandardFileManager(null,null,null);
            Iterable iterable=manage.getJavaFileObjects(f);
            JavaCompiler.CompilationTask task=compier.getTask(null,manage,null,null,null,iterable);
            task.call();
            manage.close();
        }

    载入虚拟机    java 自定义类加载器

    public static Object jvmLoad() throws Exception {
            //包+类名
            Class proxyClass=IPeople.class.getClassLoader().loadClass("c.b.People");
            return proxyClass;
        }

    利用反射生成代理对象

    public static Object newInstance(Class proxyClass) throws Exception {
            //通过无参构造方法实例化
            Object object=proxyClass.getDeclaredConstructor(null).newInstance();
            return object;
        }

    main入口方法

     public static void main(String[] args) throws Exception {
            String src=createContent();
            File f=createfile(src);
            compier(f);
            Class clazz=jvmLoad();
            IPeople people=(IPeople) newInstance(clazz);
            people.say();
         f.delete(); }

     记得最后调用删除文件功能,People.java不应该出现在编译文件这个地方。

  • 相关阅读:
    js实现各种复制到剪贴板的方法
    PowerDesigner生成数据字典
    oracle实用sql之将逗号分割的字符串分割多个列
    ROW_NUMBER() OVER()函数用法;(分组,排序),partition by
    SQL Server 2008中的CTE递归查询得到一棵树
    【GoLang】GoLang 错误处理 -- 使用 error is value 的思路处理,检查并处理error
    【GoLang】golang 报管理工具 Godep 介绍
    【GoLang】GoLang 错误处理 -- 使用异常的思路进行处理
    【GoLang】GoLang 官方 对 error 处理的意见
    【GoLang】panic defer recover 深入理解
  • 原文地址:https://www.cnblogs.com/guoyansi19900907/p/12724871.html
Copyright © 2011-2022 走看看