后端经典面试题合集, JDK 动态代理和 CGLIB 动态代理的区别是什么?
后端经典面试题合集, JDK 动态代理和 CGLIB 动态代理的区别是什么?
QA
Step 1
Q:: JDK 动态代理和 CGLIB 动态代理的区别是什么?
A:: JDK 动态代理和 CGLIB 动态代理的主要区别在于它们的实现方式和适用场景。JDK 动态代理是基于接口的代理,它要求被代理的类必须实现一个或多个接口。JDK 动态代理在运行时生成代理类,主要通过 java.lang.reflect.Proxy
类来实现。CGLIB 动态代理则是基于类的代理,它通过生成目标类的子类来创建代理对象,不要求目标类必须实现接口。CGLIB 使用 ASM 字节码生成框架来在运行时生成代理类。由于是基于子类的方式,CGLIB 不能代理 final 方法。
Step 2
Q:: JDK 动态代理的实现原理是什么?
A:: JDK 动态代理的实现依赖于 Java 的反射机制。它通过 java.lang.reflect.Proxy
类来创建代理对象,并通过 InvocationHandler
接口来处理方法的调用。当调用代理对象的方法时,实际会调用 InvocationHandler.invoke()
方法,该方法接收被代理方法的信息,并可以在其中添加自定义逻辑(如日志记录、权限检查等),然后再决定是否调用原方法。
Step 3
Q:: CGLIB 动态代理的实现原理是什么?
A:: CGLIB 动态代理的实现原理是通过生成目标类的子类,并在子类中覆盖父类的方法。CGLIB 使用 ASM 字节码生成框架在运行时生成代理类的字节码,从而创建代理对象。代理类会拦截对目标方法的调用,并在调用前后执行额外的逻辑。由于 CGLIB 是通过子类代理的方式实现的,所以它不能代理 final 类和 final 方法。
Step 4
Q:: JDK 动态代理和 CGLIB 动态代理各自的优缺点是什么?
A:: JDK 动态代理的优点是实现简单,只要目标类实现了接口就可以进行代理,且生成的代理类较为轻量。缺点是只能代理实现了接口的类。CGLIB 动态代理的优点是可以代理没有实现接口的类,适用面更广。缺点是生成的代理类性能较低,且不能代理 final 类和 final 方法。此外,CGLIB 的实现更为复杂,生成的代理类占用的内存较多。