工作方式不同:
- JDK动态代理:生成了一个匿名类,这个匿名类实现了和被代理类所实现的接口,并且继承了Proxy类。匿名类的每个方法名称跟被代理类相同,调用了实现invocationHandler接口的拦截器的invoke方法,因此所有的增强逻辑都在invoke方法里通过反射实现的。
- CGLIB动态代理利用了ASM框架,对代理类的class字节码修改生成子类,并覆盖增强其方法实现。
限制条件不同:
- JDK动态代理只能对实现了接口的类生成代理
- CGLIB对类生成子类进行代理,可以无接口,但是对于final类和方法无法继承,因此无法代理。
Spring对于两者代理的选择:
- 对于实现了接口的bean,会默认选择JDK代理
- 对于没有实现接口的bean,只能使用CGLIB代理
- 对于实现接口的bean,可以强制指定使用CGLIB代理
参考:
- Cglib和jdk动态代理的区别 https://www.cnblogs.com/sandaman2019/p/12636727.html
- Java JDK 动态代理 https://blog.csdn.net/jiankunking/article/details/52143504