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="\r\n";
        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不应该出现在编译文件这个地方。

 

posted @   思思博士  阅读(295)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2014-04-18 ckplayer的Error #2033:Can not call javascript:ckstyle()解决
点击右上角即可分享
微信分享提示