JDK动态代理是使用反射机制生成实现了代理接口的匿名类,cglib是使用字节码处理框架asm,加载代理对象类的class文件后通过修改字节码生成子类。
因此jdk动态代理基于接口,要求被代理对象必须实现接口,cglib动态代理基于继承,被代理对象类不能为final。
两者相比,jdk创建代理对象效率高;cglib代理对象执行效率高。
Spring 5.x 中 AOP 依旧默认使用 JDK 动态代理。SpringBoot 2.x 开始,为了解决使用 JDK 动态代理可能导致的类型转化异常默认使用 CGLIB。可使用配置修改。
为什么JDK动态代理可能导致类型转化异常?
https://www.cnblogs.com/super-admin/p/9653274.html
如上代码,获取bean后,为了使用进行强转。但是由于底层为JDK动态代理,我们获取的类为代理类,而代理类和我们想要的目标类实现了共同的接口但不是同一个类。而cglib就不会发生这个问题。上图的解决方案是强转为IService接口。这也体现了为什么应该面向接口编程,和依赖倒置原则。