源码层面学习动态代理

前言

在Java中,动态代理主要分为CGLIB动态代理和JDK动态代理,我们从Hutool的源码也可一窥这两者的使用方式和区别;

CGLIB动态代理

JDK动态代理

使用场景

CglibInterceptor和JdkInterceptor都是Hutool提供的代理工具,用于在运行时动态地创建对象的代理,以拦截方法调用。它们的主要区别在于代理机制的实现方式和使用场景:

  1. 实现方式:

    • CglibInterceptor:基于CGLIB库实现,通过字节码技术动态生成目标类的子类,并在子类中重写方法来实现拦截。这种方式可以代理没有实现接口的类。
    • JdkInterceptor :基于Java原生的java.lang.reflect.Proxy类实现,只能代理实现了接口的类。通过实现InvocationHandler接口,在invoke方法中定义拦截逻辑。
  2. 使用场景:

    • CglibInterceptor:适用于需要代理没有实现接口的类的情况。由于CGLIB可以创建目标类的子类,因此可以对类中的所有方法进行拦截,包括私有方法(通过桥接方法)。
    • JdkInterceptor:适用于代理实现了接口的类。由于Java原生代理的限制,只能拦截接口中声明的方法。
  3. 性能:

    • CGLIB由于需要进行字节码操作,创建代理对象的开销可能会比JDK原生代理稍大一些。但在方法调用层面,CGLIB可以提供与目标对象相似的性能。
    • JDK原生代理在创建代理对象时开销较小,但在方法调用时,由于需要通过反射机制,可能会有一定的性能损失。
  4. 功能:

    • CGLIB提供了一些额外的功能,比如可以处理final方法的拦截(通过FastClass机制)。
    • JDK原生代理则依赖于Java反射API提供的功能。
  5. 兼容性:

    • CGLIB可以代理任何类,包括final类和方法,但可能会有一些限制,比如不能代理被标记为final的类。
    • JDK原生代理只能代理实现了接口的类,不能代理final类。

选择使用CglibInterceptor还是JdkInterceptor,通常取决于具体的使用场景和需求。如果需要代理的类没有实现接口,或者需要拦截类中的所有方法(包括私有方法),则CglibInterceptor可能是更好的选择。如果代理的类已经实现了接口,并且对性能有较高要求,那么JdkInterceptor可能更合适。

相关推荐
9624561 分钟前
餐饮 SaaS 优惠券系统架构演进(三):优惠计算引擎——商品级计价、冲突策略与优惠分摊
java·数据库·spring boot
vx_Biye_Design4 分钟前
expressDeepSeek社团咨询助手的学生社团管理系统60746-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·课程设计·express
传奇开心果编程10 分钟前
【ArkUI进阶练中学】第13课:元服务与卡片开发
学习·ui·华为·harmonyos
vx_Biye_Design18 分钟前
springboot宠物领养与救助平台64334-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·mysql·课程设计·宠物
泡茶喝茶写代码20 分钟前
A股量化数据工程:从 REST 接口到策略信号(第 5 篇):板块成分股映射与对齐
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据接口
vx_Biye_Design21 分钟前
django就业信息推荐系统61953-计算机课程设计、毕业设计
java·vue.js·spring boot·python·架构·django·课程设计
知守观37 分钟前
HTML 转 PDF 方案实战:iTextPDF 与 wkhtmltopdf 踩坑复盘,附 Flying Saucer / openhtmltopdf 选型对比
java·后端
2601_9620715740 分钟前
类变量和全局变量的隔离性有什么区别?
java·开发语言·jvm
海绵宝宝转agent1 小时前
LeetCode100 LRU缓存思路讲解
java·开发语言·缓存
专业程序开发源1 小时前
springboot高校学生社团管理系统74810-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计