当前位置: 首页 > java >正文

JDK动态代理和CGLIB动态代理的区别?

大家好,我是锋哥。今天分享关于【JDK动态代理和CGLIB动态代理的区别?】面试题。希望对大家有帮助;

JDK动态代理和CGLIB动态代理的区别?

1000道 互联网大厂Java工程师 精选面试题-Java资源分享网

JDK动态代理和CGLIB动态代理是Java中实现代理模式的两种方式,它们的主要区别在于代理对象的生成方式和应用场景。以下是它们的具体区别:

1. 代理对象的生成方式

  • JDK动态代理

    • JDK动态代理是基于接口的代理,代理对象必须实现一个或多个接口。
    • 通过java.lang.reflect.Proxy类和InvocationHandler接口来创建代理对象。
    • 生成的代理对象是实现了接口的类。

    示例代码:

    public interface MyInterface {void doSomething();
    }public class MyInterfaceImpl implements MyInterface {public void doSomething() {System.out.println("Doing something!");}
    }public class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method call");Object result = method.invoke(target, args);System.out.println("After method call");return result;}
    }public class Main {public static void main(String[] args) {MyInterface target = new MyInterfaceImpl();MyInterface proxy = (MyInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new MyInvocationHandler(target));proxy.doSomething();}
    }
    

  • CGLIB动态代理

    • CGLIB(Code Generation Library)是基于类的代理,代理对象是通过继承目标类来实现的。
    • CGLIB使用字节码技术动态生成目标类的子类,并重写目标类的方法来创建代理对象。
    • 生成的代理类继承了目标类,因此不需要目标类实现接口。

    示例代码:

    public class MyClass {public void doSomething() {System.out.println("Doing something!");}
    }public class MyCglibProxy implements MethodInterceptor {private Object target;public MyCglibProxy(Object target) {this.target = target;}public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method call");Object result = method.invoke(target, args);System.out.println("After method call");return result;}
    }public class Main {public static void main(String[] args) {MyClass target = new MyClass();Enhancer enhancer = new Enhancer();enhancer.setSuperclass(MyClass.class);enhancer.setCallback(new MyCglibProxy(target));MyClass proxy = (MyClass) enhancer.create();proxy.doSomething();}
    }
    

2. 是否依赖接口

  • JDK动态代理:必须依赖接口,目标类需要实现一个或多个接口。
  • CGLIB动态代理:不依赖接口,代理对象是通过继承目标类创建的,可以对普通类进行代理。

3. 性能差异

  • JDK动态代理:由于JDK动态代理依赖反射机制(Method.invoke()),在某些场景下性能较差,尤其是在方法调用频繁的情况下。
  • CGLIB动态代理:由于是通过继承目标类并重写方法来实现的,性能比JDK动态代理更高,但生成的代理类比较重,且需要使用字节码生成库(CGLIB),所以性能不如直接实现接口的JDK代理。

4. 生成的代理类的特点

  • JDK动态代理:生成的代理类实现了目标类的所有接口,代理类和目标类的实例是完全不同的对象。
  • CGLIB动态代理:生成的代理类是目标类的子类,代理类继承了目标类的方法,并重写了需要增强的方法。

5. 适用场景

  • JDK动态代理:适用于目标类实现了接口的情况。如果目标类没有实现接口,JDK动态代理不能使用。
  • CGLIB动态代理:适用于目标类没有接口的情况,或者你希望通过类继承的方式进行代理。但需要注意,CGLIB无法代理final类和final方法。

6. 代理对象的类型

  • JDK动态代理:生成的代理对象是接口类型的实例,实际调用会通过InvocationHandler来处理。
  • CGLIB动态代理:生成的代理对象是目标类的子类,代理对象是目标类的类型。

总结:

特性JDK动态代理CGLIB动态代理
代理方式基于接口的代理基于类的代理
是否需要接口需要接口不需要接口,使用类继承
性能相对较慢,使用反射更快,直接继承并重写方法
代理的对象类型代理类实现接口代理类是目标类的子类
适用场景目标类实现了接口的情况目标类没有接口或需要对类进行代理
final类的支持支持,final方法不可代理不支持,final类和final方法无法代理

选择使用JDK动态代理还是CGLIB动态代理,主要取决于你的应用场景。如果目标类已经实现了接口,且希望通过接口代理,JDK动态代理是更优选择;如果目标类没有接口,则需要使用CGLIB动态代理。

http://www.xdnf.cn/news/5633.html

相关文章:

  • 《Head First 设计模式》第一章 - 笔记
  • 关于nextjs中next-sitemap插件生成文件样式丢失问题及自定义样式处理
  • 开启WSL的镜像网络模式
  • git和gdb
  • 《Flutter社交应用暗黑奥秘:模式适配与色彩的艺术》
  • hashCode()和equals(),为什么使用Map要重写这两个,为什么重写了hashCode,equals也需要重写
  • Decimal.js 的常用方法
  • HNUST软件测试B考前最终复习
  • 密码学--仿射密码
  • 配置文件介绍xml、json
  • (自用)Java学习-5.12(Redis,B2C电商)
  • 【A2A】根据A2A的协议标准,不同架构的2个大模型agent的交互,是否都需要实现和对接 client和server模块?
  • NuPlan v1.1 数据集校验
  • 网络原理(TCP协议性质)
  • ARM64内核内存空间布局
  • 0512 - 2094. 找出 3 位偶数
  • Spring Boot动态配置修改全攻略
  • Docker从0到1:入门指南
  • 基于卡尔曼滤波的传感器融合技术的多传感器融合技术(附战场环境模拟可视化代码及应用说明)
  • 量子加密通信:守护信息安全的未来之盾
  • 2025年第十六届蓝桥杯软件赛省赛C/C++大学A组个人解题
  • 51c大模型~合集127
  • 用C语言实现的——一个完整的AVL树的交互式系统
  • NHANES指标推荐:sNfL
  • 几何_平面方程表示_点+向量形式
  • linux内存管理
  • C盘扩容方法:如何扩展不相邻的分区?
  • 8天Python从入门到精通【itheima】-1~5
  • Baumer工业相机堡盟工业相机在使用光源时如何选择蓝光还是红光
  • 制作一款打飞机游戏43:行为编辑