动态代理原理(JDK vs CGLIB)?
请解释Java中动态代理的两种实现方式:JDK动态代理和CGLIB动态代理。说明各自的底层原理(反射/字节码增强)、使用限制、性能对比以及在Spring AOP中的应用。
回答
我是大山
JDK动态代理:
- 原理:实现InvocationHandler接口,通过Proxy.newProxyInstance()生成代理类
- 要求:目标对象必须实现至少一个接口
- 底层:运行时动态生成一个实现目标接口的代理类字节码,通过反射调用InvocationHandler.invoke()
- 性能:创建代理对象快,调用慢(反射开销)
CGLIB动态代理:
- 原理:通过ASM字节码框架,生成目标类的子类,重写非final方法
- 要求:目标类不能是final,被代理的方法不能是final或static
- 底层:生成子类字节码,方法调用通过FastClass机制(非反射)
- 性能:创建代理对象慢(需生成字节码),调用快(FastClass索引调用)
Spring AOP使用策略:
- 目标类实现接口 → JDK动态代理(默认)
- 目标类未实现接口 → CGLIB代理
- Spring Boot 2.x+默认使用CGLIB(proxy-target-class=true)
对比:JDK代理仅支持接口代理;CGLIB可代理类但无法处理final方法/类。