CGLIB 与 JDK 动态代理的对比
| 特性 | CGLIB 动态代理 | JDK 动态代理 |
|---|---|---|
| 机制 | 通过继承目标类,生成子类 | 通过实现目标接口,生成实现类 |
| 要求 | 目标类不能是 final | 目标类必须实现至少一个接口 |
| 性能 | 通常更高。生成类后,方法调用通过 FastClass 机制直接调用,避免了反射。 | 较低。方法调用通过 Java 反射机制。 |
| 方法限制 | 无法代理 final / private 方法 | 可以代理接口中的所有方法 |
| 依赖 | 需要引入 cglib 库(如 cglib:cglib:3.3.0) | 仅依赖 Java 标准库 |
Spring 框架的选择策略:
在 Spring AOP 中,框架会自动根据目标类的特点选择代理方式:
- 如果目标对象实现了接口 -> 默认使用 JDK 动态代理。
- 如果目标对象没有实现接口 -> 使用 CGLIB 动态代理。
- 你也可以通过配置强制 Spring 始终使用 CGLIB(
<aop:aspectj-autoproxy proxy-target-class="true"/>)