0

0

Java中的动态代理实现方式_JDK原生代理与CGLIB字节码生成的区别

P粉602998670

P粉602998670

发布时间:2026-02-25 16:59:03

|

764人浏览过

|

来源于php中文网

原创

jdk动态代理仅支持接口代理,因其实现依赖proxy和invocationhandler生成接口实现类,无法代理无接口的类;cglib通过继承实现代理,要求类与方法非final,且不代理static/private方法。

java中的动态代理实现方式_jdk原生代理与cglib字节码生成的区别

JDK动态代理只能代理接口,不是类

因为JDK动态代理底层靠 java.lang.reflect.ProxyInvocationHandler 实现,它在运行时生成一个实现目标接口的新类(比如 $Proxy0),但无法为没有接口的类生成代理。如果你试图对一个只有具体类、没实现任何接口的对象做JDK代理,会直接抛出 IllegalArgumentException: target class is not an interface

实操建议:

立即学习Java免费学习笔记(深入)”;

Matlab语言的特点 中文WORD版
Matlab语言的特点 中文WORD版

本文档主要讲述的是Matlab语言的特点;Matlab具有用法简单、灵活、程式结构性强、延展性好等优点,已经逐渐成为科技计算、视图交互系统和程序中的首选语言工具。特别是它在线性代数、数理统计、自动控制、数字信号处理、动态系统仿真等方面表现突出,已经成为科研工作人员和工程技术人员进行科学研究和生产实践的有利武器。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载
  • 确认被代理对象是否实现了至少一个接口;没接口就别硬用JDK代理
  • 如果必须代理类(比如第三方库的 final 类或无源码类),立刻转向 CGLIB
  • Spring AOP 默认优先用JDK代理,但只要目标类没接口,它会自动 fallback 到 CGLIB——这点容易被忽略,以为配置了 proxy-target-class="false" 就一定走JDK,其实 Spring 会自己“违约”

CGLIB代理要求类不能是final,方法也不能是final

CGLIB通过继承目标类生成子类来实现代理,所以它需要能重写目标类的方法。一旦类被声明为 final,或者某个方法是 final,CGLIB在生成子类时就会失败,抛出类似 java.lang.IllegalArgumentException: Cannot subclass final class xxxMethod is not public(因为 private/final 方法不可覆写)。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 检查你要代理的类和关键方法,去掉 final 修饰符是最直接的解法
  • 如果类来自外部 jar 且无法修改,考虑用 JDK 接口代理 + 包装器模式兜底,而不是强行 CGLIB
  • CGLIB 默认不代理 staticprivate 方法,这点和 JDK 代理一致,但新手常误以为“能代理类=能代理所有方法”

InvocationHandler 和 MethodInterceptor 的拦截逻辑差异

JDK 的 InvocationHandler.invoke() 是一次性接收方法调用,返回值由你决定;CGLIB 的 MethodInterceptor.intercept() 多了一个 MethodProxy 参数,它封装了对父类方法的快速调用(methodProxy.invokeSuper()),比反射快,但必须用它才能真正触发原方法执行。

常见错误现象:

  • 在 CGLIB 的 intercept() 里直接写 method.invoke(obj, args) —— 这会绕过 CGLIB 的优化,甚至引发无限递归(因为 obj 就是代理子类实例)
  • 忘记调用 methodProxy.invokeSuper(),导致原方法完全不执行,静默失效
  • JDK 中 invoke()proxy 参数是代理对象本身,而 CGLIB 的 obj 是目标类实例(非代理),别混淆用途

性能与字节码兼容性:JDK快在启动,CGLIB快在运行

JDK代理生成类极快(基于已有的 Proxy 模板),但每次方法调用都要走反射(Method.invoke()),开销略高;CGLIB首次生成子类较慢(要解析字节码、生成新类),但后续调用是直接 invokevirtual,几乎无额外成本。

影响点:

  • 高频调用场景(如 RPC 拦截、日志埋点),CGLIB 实际吞吐更高
  • 应用启动阶段大量创建代理(如 Spring 初始化上百个 Bean),JDK 更轻量,CGLIB 可能拖慢启动速度
  • CGLIB 依赖 asm 库,不同 JDK 版本下需匹配对应版本(例如 JDK 17+ 要用 asm 9.2+),否则报 UnsupportedClassVersionErrorjava.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor

真实项目里,JDK 和 CGLIB 往往共存,选哪个不只看“能不能”,更要看“谁在哪儿卡得最疼”。比如一个接口有 5 个实现类,其中 4 个有接口、1 个没接口还带 final 方法——这时候混合策略比强行统一更稳。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

144

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

81

2026.01.26

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1653

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

506

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2308

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

40

2026.01.19

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

687

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

22

2025.12.06

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

125

2026.02.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.9万人学习

C# 教程
C# 教程

共94课时 | 10.2万人学习

Java 教程
Java 教程

共578课时 | 72.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号