proxy.getproxyclass是缓存与生成协调入口,真正字节码由proxygenerator.generateproxyclass在内存中按jvm规范构造;weakcache以类加载器和接口数组为键实现弱引用缓存;未命中时生成com.sun.proxy.$proxyn类,统一委托invoke方法;defineclass直接内存加载,不落盘;仅支持接口代理,逻辑固化不可扩展。

Proxy.getProxyClass 不直接生成字节码,而是协调缓存查找与按需生成的入口方法;真正拼装字节码的是隐藏的 ProxyGenerator.generateProxyClass,它在内存中严格遵循 JVM ClassFile 规范构造二进制流,不落盘、不依赖文件系统。
缓存机制:WeakCache 控制类复用
每次调用 getProxyClass0(loader, interfaces) 时,JDK 先查 proxyClassCache(基于 WeakCache 实现):
- 键由类加载器 + 接口数组内容共同决定,相同组合命中缓存,避免重复生成
- 缓存值是已定义好的
Class>对象,不是字节码数组 - 弱引用设计防止 ClassLoader 泄漏,卸载后对应代理类可被回收
字节码生成:ProxyGenerator 拼接固定结构
缓存未命中时,触发 ProxyClassFactory 的 apply 方法,最终调用私有 API:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
generateProxyClass(String name, Class>[] interfaces)返回byte[] - 生成的类名形如
com.sun.proxy.$ProxyN,父类固定为java.lang.reflect.Proxy - 自动实现所有传入接口,每个方法体统一编译为:
调用h.invoke(this, method, args),其中h是构造时传入的InvocationHandler - 不生成任何字段(除继承自 Proxy 的
h),也不处理默认方法或静态方法
类加载:defineClass 直接注入 JVM
拿到字节码后,JDK 使用当前 loader 的 defineClass 原生加载:
- 跳过验证、准备、解析等常规类加载流程中的文件读取环节
- 字节码从内存直接送入 JVM 类型系统,立即可反射获取、实例化
- 可通过设置
sun.misc.ProxyGenerator.saveGeneratedFiles=true让其尝试写 .class 文件(仅调试用途,非默认行为)
关键限制:接口绑定与不可定制性
整个链路的设计决定了它的边界:
- 必须至少有一个接口,不支持代理普通类(无接口)、final 类或基本类型
- 方法拦截逻辑固化:所有接口方法强制路由到同一个
invoke,无法按方法签名差异化处理 - 字节码结构不可插桩——不能加日志字段、不能改访问修饰符、不能注入 try-catch 模板
- 没有提供公开扩展点,无法替换生成策略或修改命名规则










