Spring循环依赖 三级缓存

AOP(Aspect-Oriented Programming) 切面就是方法执行前后代理

IOC 控制反转(框架控制注册、注入依赖)

image.png

对比

对比项 JDK 动态代理 CGLIB (Spring 使用的是其内部 fork 版本) 到底是哪种?(结论)
依赖 必须有接口 不需要接口 CGLIB 胜 (适用性更广)
原理 java.lang.reflect.Proxy (基于反射+接口实现) ASM 字节码生成 (基于继承子类) -
性能 (创建) 极快 稍慢 (需要生成字节码) 差异微乎其微
性能 (调用) JDK 8+ 后性能大幅提升,与 CGLIB 差距很小 快 (直接方法调用,非反射) 平局 (业务开发中无感)
final 类 无法代理 (代理类本身就是 final) 无法代理 (无法生成子类) 都不能
final 方法 可以代理 (只要接口方法不是 final) 无法代理 (无法覆写) JDK 胜 (但在 CGLIB 默认下需注意)
Spring Boot 默认 false true (默认强制使用) CGLIB

**CGLib的动态代理好像更加强大,而JDK的动态代理却限制颇多。而且前面也提过,CGLib的代理对象,执行代理方法的速度更快,只是生成代理类的效率较低。但是我们使用到的bean大部分都是单例的,并不需要频繁创建代理类,也就是说CGLib应该会更合适。但是为什么Spring默认使用JDK呢?这我也不太清楚,网上也没有找到相关的描述(如果有人知道,麻烦告诉我)。但是据说SpringBoot现在已经默认使用CGLib作为AOP**的实现了。

**Spring默认使用JDK**动态代理

**sringBoot现在已经默认使用CGLib作为AOP**的实现


 * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
 * Auto-configuration} for Spring's AOP support. Equivalent to enabling
 * {@link EnableAspectJAutoProxy @EnableAspectJAutoProxy} in your configuration.
 * <p>
 * The configuration will not be activated if {@literal spring.aop.auto=false}. The
 * {@literal proxyTargetClass} attribute will be {@literal true}, by default, but can be
 * overridden by specifying {@literal spring.aop.proxy-target-class=false}.

cjlib

通过修改字节码生成目标对象的子类作为代理,覆盖父类方法进行增强。CGLIB 基于 ASM 框架操作字节码。

image.png

jdk

• 适用条件:目标对象实现了接口。 • 实现原理:通过 java.lang.reflect.Proxy 类和 InvocationHandler 接口实现。调用 Proxy.newProxyInstance() 方法生成代理对象,代理对象将方法调用转发给 InvocationHandler.invoke() 方法,从而在方法执行前后添加增强逻辑。

资料

https://spring.hhui.top/spring-blog/2019/03/10/190310-SpringCloud基础篇AOP之拦截优先级详解/

https://pdai.tech/md/spring/spring-x-framework-aop-source-4.html