首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
一 . 前言
之前说了 AOP初始化 和 AOP 代理类的创建 , 这一篇来看一下 AOP 对请求的拦截
AOP 拦截的起点是 DynamicAdvisedInterceptor , 该对象在 CglibAopProxy -> getProxy -> getCallbacks
二 . 拦截的发起
2.1 CglibAopProxy 的拦截开始
1 | JAVA复制代码C- DynamicAdvisedInterceptor # intercept |
2.2 Interceptor 执行 Proceed
上一节创建后 CglibMethodInvocation 后 , 会执行 proceed , 以此调用切面类 , 此处先以 Around 为例 , 后面再看一下其他的几种调用
Step 1 : Proceed 调用逻辑 (ReflectiveMethodInvocation)
主要是调用父类的逻辑 CglibMethodInvocation extends ReflectiveMethodInvocation
1 | java复制代码public Object proceed() throws Throwable { |
MethodMatcher 对象体系 :
Step 2 : ExposeInvocationInterceptor
这里是通过 ExposeInvocationInterceptor(CglibMethodInvocation) 调用 , 该拦截器的作用为 将当前MethodInvocation公开为本地线程对象的拦截器
1 | java复制代码private static final ThreadLocal<MethodInvocation> invocation =new NamedThreadLocal<>("Current AOP method invocation"); |
Step 3 : 调用不同的拦截链
从 2.2 步骤中 , 会通过自增的方式迭代拦截器 :this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
PS : 通常链式结构是递归执行的 , 通常最先执行的在列表最后
1 | java复制代码// 调用对应的 xxxAdviceInterceptor -> [Pro25001] |
[Pro25001] : Advice 拦截链的调用
1 | java复制代码// 此处会对不同的 Advice 进行处理 , 核心带入如下 : |
Step 4 : 反射到 Advice Method
1 | java复制代码protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { |
2.3 补充其他通知的调用方式
AspectJAfterAdvice 的调用
1 | java复制代码 |
AfterReturningAdviceInterceptor 的调用
1 | java复制代码public Object invoke(MethodInvocation mi) throws Throwable { |
三 . 方法的调用
以 Around 为例 , 当执行了 ProceedingJoinPoint.proceed() 方法后 , 即开始了实际方法的调用
- Step 1 : 切面调用 pj.proceed()
- Step 2 : MethodInvocationProceedingJoinPoint 发起 proceed 操作
- Step 3 : 循环完成 , 发起方法调用
- Step 4 : 实际方法调用
3.1 MethodInvocationProceedingJoinPoint 发起 proceed 操作
PS : 此处还没有完成 , 这是构建了一个新的对象 , 从上一个链表图中可以看到 , 还要执行后续的 Before Advice
1 | JAVA复制代码public Object proceed() throws Throwable { |
3.2 Interceptor 循环完成 , 发起方法调用
补充 ReflectiveMethodInvocation 对象结构 >>
1 | java复制代码- ReflectiveMethodInvocation : 基于反射的方式,代理方法调用实现类。 |
当循环迭代完成后(currentInterceptorIndex匹配完成) :
1 | java复制代码public Object proceed() throws Throwable { |
3.3 发起实际方法调用
1 | java复制代码// Step 3 : 实际方法调用 (2.1 中初始化了该属性) |
3.4 补充 : 带参数的请求
在 MethodInvocationProceedingJoinPoint 中 ,存在一个带参数的 proceed 方法 , 用于构建带参数的 clone 对象
1 | java复制代码// 除了无参的请求 , 实际上还有个带参的请求 , 他们的请求方式是不一样的 |
直到这里 , AOP 的方法调用就完全完成了 >>
四 . 补充 AOP 的拦截链构建
这里补充看一下 AOP 链的调用逻辑
C- AdvisorChainFactory : 通知链工厂
C- DefaultAdvisorChainFactory : 实现类
4.1 DynamicAdvisedInterceptor # intercept 发起拦截链构建
1 | java复制代码public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { |
4.2 从缓存中获取拦截器
这里会优先从缓存中获取 , 缓存没有会先创建 ,再放入缓存
1 | java复制代码// 缓存集合 |
4.3 构建通知链
1 | java复制代码C- DefaultAdvisorChainFactory |
Advisor 体系结构 :
总结
到了这一篇 AOP 的主要逻辑就全部完成了 , 后续准备说说AOP 的性能分析以及补充知识点 , 等全部完成后 , 再对 AOP 逻辑进行一遍打磨
现阶段程度只是读懂了代码 , 只能看懂为什么这么用 . 等打磨的时候 ,期望能从中学到一些代码的设计精髓 , 以及写一套出来
本文转载自: 掘金