【面试问题】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 动态代理更为适合。在实际应用中,有时候也会结合使用两者,根据情况选择最合适的代理方式。

相关文章
|
10天前
|
Java
【Java集合类面试二十八】、说一说TreeSet和HashSet的区别
HashSet基于哈希表实现,无序且可以有一个null元素;TreeSet基于红黑树实现,支持排序,不允许null元素。
|
10天前
|
存储 Java 索引
【Java集合类面试二十四】、ArrayList和LinkedList有什么区别?
ArrayList基于动态数组实现,支持快速随机访问;LinkedList基于双向链表实现,插入和删除操作更高效,但占用更多内存。
【多线程面试题十】、说一说notify()、notifyAll()的区别
notify()唤醒单个等待对象锁的线程,而notifyAll()唤醒所有等待该对象锁的线程,使它们进入就绪队列竞争锁。
|
7天前
|
设计模式 Java C++
揭秘!JDK动态代理VS CGLIB:一场关于Java代理界的‘宫心计’,你站哪队?
【8月更文挑战第24天】Java 动态代理是一种设计模式,允许在不改动原类的基础上通过代理类扩展功能。主要实现方式包括 JDK 动态代理和 CGLIB。前者基于接口,利用反射机制在运行时创建代理类;后者采用继承方式并通过字节码技术生成子类实现类的代理。两者在实现机制、性能及适用场景上有明显差异。JDK 动态代理适用于有接口的场景,而 CGLIB 更适合代理未实现接口的类,尽管性能更优但存在一些限制。开发者可根据需求选择合适的代理方式。
30 0
|
9天前
|
缓存 Java 编译器
JRE、JDK、JVM 和 JIT 之间的区别详解
【8月更文挑战第22天】
26 0
|
10天前
|
算法 Java
【多线程面试题十八】、说一说Java中乐观锁和悲观锁的区别
这篇文章讨论了Java中的乐观锁和悲观锁的区别,其中悲观锁假设最坏情况并在访问数据时上锁,如通过`synchronized`或`Lock`接口实现;而乐观锁则在更新数据时检查是否被其他线程修改,适用于多读场景,并常通过CAS操作实现,如Java并发包`java.util.concurrent`中的类。
|
10天前
|
Java
【多线程面试题十三】、说一说synchronized与Lock的区别
这篇文章讨论了Java中`synchronized`和`Lock`接口在多线程编程中的区别,包括它们在实现、使用、锁的释放、超时设置、锁状态查询以及锁的属性等方面的不同点。
【多线程面试题九】、说一说sleep()和wait()的区别
sleep()和wait()的主要区别在于sleep()是Thread类的静态方法,可以在任何地方使用且不会释放锁;而wait()是Object类的方法,只能在同步方法或同步代码块中使用,并会释放锁直到相应线程通过notify()/notifyAll()重新获取锁。
【多线程面试题 三】、 run()和start()有什么区别?
run()方法定义线程执行的任务,而start()方法启动线程,使得run()在新的线程中异步执行;直接调用run()方法只会同步执行run()中的代码,不会创建新线程。
|
12天前
|
Java 关系型数据库 MySQL
"解锁Java Web传奇之旅:从JDK1.8到Tomcat,再到MariaDB,一场跨越数据库的冒险安装盛宴,挑战你的技术极限!"
【8月更文挑战第19天】在Linux上搭建Java Web应用环境,需安装JDK 1.8、Tomcat及MariaDB。本指南详述了使用apt-get安装OpenJDK 1.8的方法,并验证其版本。接着下载与解压Tomcat至`/usr/local/`目录,并启动服务。最后,通过apt-get安装MariaDB,设置基本安全配置。完成这些步骤后,即可验证各组件的状态,为部署Java Web应用打下基础。
28 1