自学内容网 自学内容网

源码层面学习动态代理

前言

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

CGLIB动态代理

JDK动态代理

使用场景

CglibInterceptorJdkInterceptor都是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可能更合适。


原文地址:https://blog.csdn.net/weixin_40709965/article/details/140276960

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!