【面试问题】JDK 动态代理与 CGLIB 区别?

简介: 【1月更文挑战第27天】【面试问题】JDK 动态代理与 CGLIB 区别?

JDK 动态代理和 CGLIB(Code Generation Library)是两种常见的 Java 动态代理技术,它们在实现方式和应用场景上存在一些区别。

1. 实现方式:

  • JDK 动态代理:
  • 使用 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口。
  • 只能代理实现了接口的类,生成的代理对象是接口的实现类。
  • 通过 Java 反射机制在运行时动态生成代理类。
  • CGLIB 动态代理:
  • 使用 CGLIB 库,它通过字节码技术生成目标类的子类作为代理。
  • 可以代理没有实现接口的类。
  • 通过修改字节码生成新的类,使其成为目标类的子类,从而实现代理。

2. 代理对象类型:

  • JDK 动态代理:
  • 代理对象实现了被代理接口。
  • 要求目标类必须实现接口,因为代理对象是接口的实现类。
  • CGLIB 动态代理:
  • 代理对象是目标类的子类。
  • 可以代理没有实现接口的类,包括 final 类。

3. 性能:

  • JDK 动态代理:
  • 生成的代理类较轻量,创建速度相对较快。
  • 在方法调用上的性能比 CGLIB 略低,因为使用了 Java 反射机制。
  • CGLIB 动态代理:
  • 生成的代理类较重量,创建速度相对较慢。
  • 在方法调用上的性能比 JDK 动态代理高,因为直接通过生成的子类调用方法,无需通过反射。

4. 对目标类要求:

  • JDK 动态代理:
  • 要求目标类必须实现接口,否则无法生成代理。
  • CGLIB 动态代理:
  • 可以代理没有实现接口的类。

5. 应用场景:

  • JDK 动态代理:
  • 适用于对接口进行代理的场景,如 AOP(面向切面编程)。
  • CGLIB 动态代理:
  • 适用于对类进行代理的场景,特别是当目标类没有实现接口或者需要代理类为目标类的子类时。

6. 可见性和访问控制:

  • JDK 动态代理:
  • 受限于接口中声明的方法,只能代理接口中的公共方法。
  • CGLIB 动态代理:
  • 可以代理目标类中的所有非 final 的方法,包括私有方法。、


选择使用 JDK 动态代理还是 CGLIB 动态代理取决于具体的需求和场景。如果目标类已经实现了接口,且要求代理对象也实现相同接口,那么 JDK 动态代理是个不错的选择。如果目标类没有实现接口,或者需要代理类为目标类的子类,那么 CGLIB 动态代理更为适合。在实际应用中,有时候也会结合使用两者,根据情况选择最合适的代理方式。

相关文章
|
存储 算法 Java
JvM JDK JRE 三者区别与联系详解
本文深入解析了Java编程中的三个核心概念:JVM(Java虚拟机)、JDK(Java开发工具包)和JRE(Java运行环境)。JVM是执行Java字节码的虚拟计算机,实现“一次编译,到处运行”;JDK包含JRE及开发工具,用于编写和调试Java程序;JRE负责运行已编译的Java程序。文章详细阐述了它们的功能、组成及应用场景,并通过实例说明其在实际开发中的作用,帮助开发者理解三者联系与区别,提升开发效率与问题解决能力。适合Java初学者及进阶开发者学习参考。
1691 3
|
存储 算法 架构师
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
|
Java Spring
JDK动态代理和CGLIB动态代理的区别
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理: ● JDK动态代理只提供接口的代理,不支持类的代理Proxy.newProxyInstance(类加载器, 代理对象实现的所有接口, 代理执行器) ● CGLIB是通过继承的方式做的动态代理 , 如果某个类被标记为final,那么它是无法使用 CGLIB做动态代理的。Enhancer.create(父类的字节码对象, 代理执行器)
|
监控 Java API
JDK动态代理和CGLIB动态代理
Java动态代理允许在运行时创建代理对象,增强或拦截目标类方法的执行。主要通过两种方式实现:JDK动态代理和CGLIB动态代理。JDK动态代理基于接口,利用`java.lang.reflect.Proxy`类和`InvocationHandler`接口;CGLIB则通过字节码技术生成目标类的子类作为代理,适用于未实现接口的类。两者均用于在方法执行前后添加额外逻辑,如日志记录、权限控制等,广泛应用于AOP框架中。
498 2
|
监控 Java API
JDK动态代理和CGLIB动态代理
Java动态代理允许在运行时创建代理对象,增强或拦截目标类的方法调用,无需修改原代码。它有两种主要实现方式:JDK动态代理和CGLIB动态代理。 - **JDK动态代理**:通过`java.lang.reflect.Proxy`类和`InvocationHandler`接口实现,适用于实现了接口的类。它在方法调用前后插入额外逻辑,如日志记录、权限控制等。 - **CGLIB动态代理**:基于字节码技术,为未实现接口的类生成子类作为代理,重写父类方法以添加增强逻辑。适用于没有接口的类,但要求目标类不能是`final`类或方法。
254 1
|
Java 程序员 调度
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
681 9
|
编译器 Android开发 开发者
Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
Lambda表达式和匿名函数都是Kotlin中强大的特性,帮助开发者编写简洁而高效的代码。理解它们的区别和适用场景,有助于选择最合适的方式来解决问题。希望本文的详细讲解和示例能够帮助你在Kotlin开发中更好地运用这些特性。
454 9
|
Java API 数据安全/隐私保护
探索Java动态代理的奥秘:JDK vs CGLIB
动态代理是一种在 运行时动态生成代理类的技术,无需手动编写代理类代码。它通过拦截目标方法的调用,实现对核心逻辑的 无侵入式增强(如日志、事务、权限控制等)。
533 0
探索Java动态代理的奥秘:JDK vs CGLIB
|
12月前
|
存储 Ubuntu 安全
在Ubuntu 16.04上安装openjdk-6/7/8-jdk的步骤
在整个安装过程中,你可能需要管理员权限,因此你可能要使用 `sudo` 来获取必要的权限。记得做完每一个步骤后,都要检查输出,以确保没有发生错误,并且每项操作都成功完成。如果在安装过程中遇到问题,查看 `/var/log/` 下的日志文件对于问题的解决可能是有帮助的。
738 21
|
IDE Ubuntu Java
在Ubuntu18.04安装兼容JDK 8的Eclipse集成开发环境的指南。
完成以上步骤后,您将在Ubuntu 18.04系统上成功安装并配置了Eclipse IDE,它将与JDK 8兼容,可以开始进行Java开发工作。如果遇到任何问题,请确保每一步骤都正确执行,并检查是否所有路径都与您的具体情况相匹配。
530 11