21 spring为何针对接口用jdk动态代理

vvEcho 2025-03-02 18:22:39
Categories: Tags:

jdk为什么不能针对没有实现接口的类生成代理?

JDK动态代理的机制要求代理类必须基于接口的方法签名生成代理方法。若目标类未实现接口,则无法通过接口定义这些方法签名,导致代理类无法生成对应方法

JDK动态代理中代理类直接实现目标接口,并通过反射调用目标对象的方法;

另外由于Java不支持多继承,若JDK动态代理通过继承目标类生成代理类,则无法同时继承其他类,限制了代理类的扩展性

spring动态代理和springboot中动态代理有区别吗?

Spring默认接口基于jdk动态代理,实现类基于cglib动态代理

Springboot中默认是cglib代理,可以通过配置修改为jdk代理

1
spring.aop.proxy-target-class=false

springboot使用CGLB实现动态代理的原因?

(1) 避免类型转换异常

在 Spring Boot 2.x 之前,若目标类实现了接口,代理对象类型为接口,而非具体实现类。当用户尝试将代理对象强制转换为实现类时,可能引发 ClassCastException。

CGLIB 的改进:CGLIB 通过生成目标类的子类作为代理对象,代理类型既是接口的实现类,也是目标类的子类,解决了类型兼容性问题 。

(2) 更广泛的代理支持

无接口类代理:CGLIB可代理未实现任何接口的普通类,覆盖所有场景,而JDK动态代理仅支持接口。
统一代理策略:Spring Boot默认使用CGLIB,避免因目标类是否实现接口而切换代理方式,简化配置和调试流程。

(3) 性能与兼容性平衡

性能优势:CGLIB 在生成代理对象时通过字节码增强技术(基于 ASM)直接生成子类,减少了反射调用开销,尤其在代理大量无接口类时性能更优。
版本兼容性:Spring Boot 2.x起内置CGLIB依赖,无需手动引入,解决了早期版本中的依赖冲突问题