后端经典面试题合集, JDK 动态代理和 CGLIB 动态代理的区别是什么?
后端经典面试题合集, JDK 动态代理和 CGLIB 动态代理的区别是什么?
QA
Step 1
Q:: JDK 动态代理和 CGLIB 动态代理的区别是什么?
A:: JDK 动态代理和 CGLIB 动态代理主要区别在于:
1.
代理机制:JDK 动态代理基于 Java 接口,代理类必须实现一个或多个接口。CGLIB 动态代理则通过生成目标类的子类来创建代理对象,不要求目标类实现接口。
2.
实现方式:JDK 动态代理使用 Java 自带的 java.lang.reflect.Proxy
类和 InvocationHandler
接口来实现。CGLIB 动态代理使用字节码生成库(如 ASM)来生成目标类的子类。
3.
性能:在简单场景下,JDK 动态代理的性能一般优于 CGLIB,因为 JDK 动态代理只需要处理方法调用,而 CGLIB 需要生成字节码。但在高复杂度的场景中,CGLIB 可能更具优势。
4.
限制:JDK 动态代理只能代理实现了接口的类,而 CGLIB 可以代理任何非 final 的类。由于 CGLIB 生成的是子类,因此它不能代理 final 类,也不能代理 final 方法。
Step 2
Q:: 为什么选择使用 JDK 动态代理?
A:: 选择 JDK 动态代理的主要原因包括:
1.
简洁性:如果你的类已经实现了接口,并且接口是进行代理的主要切入点,那么使用 JDK 动态代理更加自然和简洁。
2.
Java 标准库:JDK 动态代理是 Java 自带的功能,不需要额外依赖外部库,适合在标准 Java 环境下使用。
3.
性能:在接口较少、调用简单的场景下,JDK 动态代理的性能可能优于 CGLIB。
Step 3
Q:: 为什么选择使用 CGLIB 动态代理?
A:: 选择 CGLIB 动态代理的主要原因包括:
1.
无需接口:如果你的类没有实现接口,而你又需要对其进行代理,CGLIB 是更好的选择。
2.
扩展性:CGLIB 可以代理类本身,并且可以在子类中覆盖或增强方法,这对于某些框架或库(如 Spring)而言非常有用。
3.
复杂场景:在需要对大量方法进行代理或有复杂逻辑的场景中,CGLIB 的性能可能优于 JDK 动态代理。