大家好,又见面了,我是你们的朋友全栈君。
本篇旨在让读者对Spring AOP实现原理有一个宏观上的认识,因此会丢失一些细节,具体实现参考:老实人Spring源码目录 阅读本篇文章前,希望读者对Spring Ioc以及Spring AOP的使用(@Aspect)由一定了解,话不多说,直接上图
准备工作
Service
类:有find方法跟save方法,find方法前后需要缓存操作,save方法前后需要事务操作CacheableAspect
切面类:用于在Service的find方法前后进行缓存操作TransctionlAspect
切面类:用于在Service的save方法进行事务操作LogAspect
切面类:记录所有Controller的请求日志
Spring AOP自动代理时机
在service
bean的创建过程中(也就是getBean("service")
),AOP通过BeanPostProcess后置处理器操作进行介入
分为2种情况:
- 用户自定义了
targetSource
,则bean的创建(实例化、填充、初始化)均由用户负责,Spring Ioc不会在管该代理目标对象traget
,这种情况基本上不会发生,很多人用了几年Spring可能都不知道有它的存在 - 正常情况下都是Spring Ioc完成代理对象
target
的实例化、填充、初始化。然后在初始化后置处理器中进行介入,对bean
也就是service
进行代理
创建代理操作wrapIfNecessary
所有的重点都在wrapIfNecessary
做了什么操作
代理的方法调用
创建完代理,代理如果调用方法呢?我们以Jdk动态代理
为例子,方法的调用将会触发invoke
方法。具体源码参考Jdk动态代理 底层源码
Spring AOP拦截器的执行顺序
从上面可以看出,Spring AOP的代理invoke
方法,其实是拦截器
的执行。
我们先了解一下Spring AOP的执行顺序,跟栈
很像,后进先出
AOP拦截器执行原理
那么这个拦截器链又如何保证before
在after
之前呢?而且还能保证find
方法的执行顺序?详情参考MethodInvocation拦截器调用原理
这部分实现原理通过几句话是解释不完的,只能给出图大家了解个大概
具体拦截器源码:
代码语言:javascript复制public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 先调用before方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 继续链式调用
return mi.proceed();
}
}
代码语言:javascript复制public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
private final AfterReturningAdvice advice;
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 先进行链式调用
Object retVal = mi.proceed();
// 再调用afterReturning方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}
压轴题:Spring AOP遇上循环依赖
该部分难度系数十颗星,算是Spring源码最复杂的一块,这块弄懂可以说对Spring的理解已经达到阿里水准了。这里三言两语是不可能解释清楚的,只能贴个图,大家有个宏观上的认知,详情Spring AOP遇上循环依赖
总结
Spring AOP是Spring重要的组成部分之一,本篇只是给读者宏观上的一个认识,具体还是需要阅读源码。
画图不容易啊,麻烦各位大佬给个赞!有不懂的问题可以留言,会一一解答,有写错的地方也欢迎探讨!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/192197.html原文链接:https://javaforall.cn