设为首页 加入收藏

TOP

spring5 源码深度解析----- AOP目标方法和增强方法的执行(100%理解AOP)(一)
2019-10-11 11:19:47 】 浏览:44
Tags:spring5 源码 深度 解析 ----- AOP 目标 方法 增强 执行 100% 理解

上一篇博文中我们讲了代理类的生成,这一篇主要讲解剩下的部分,当代理类调用时,目标方法和代理方法是如何执行的,我们还是接着上篇的ReflectiveMethodInvocation类Proceed方法来看

public Object proceed() throws Throwable {
    // 首先,判断是不是所有的interceptor(也可以想像成advisor)都被执行完了。
    // 判断的方法是看currentInterceptorIndex这个变量的值,增加到Interceptor总个数这个数值没有,
    // 如果到了,就执行被代理方法(invokeJoinpoint());如果没到,就继续执行Interceptor。
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }

    // 如果Interceptor没有被全部执行完,就取出要执行的Interceptor,并执行。
    // currentInterceptorIndex先自增
     Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    // 如果Interceptor是PointCut类型
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        // 如果当前方法符合Interceptor的PointCut限制,就执行Interceptor
        if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
           // 这里将this当变量传进去,这是非常重要的一点
            return dm.interceptor.invoke(this);
        }
        // 如果不符合,就跳过当前Interceptor,执行下一个Interceptor
        else {
            return proceed();
        }
    }
    // 如果Interceptor不是PointCut类型,就直接执行Interceptor里面的增强。
    else {
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

我们先来看一张方法调用顺序图

我们看到链中的顺序是AspectJAfterThrowingAdvice、AfterReturningAdviceInterceptor、AspectJAfterAdvice、MethodBeforeAdviceInterceptor,这些拦截器是按顺序执行的,那我们来看看第一个拦截器AspectJAfterThrowingAdvice中的invoke方法

AspectJAfterThrowingAdvice

 1 @Override
 2 public Object invoke(MethodInvocation mi) throws Throwable {
 3     try {
 4         //直接调用MethodInvocation的proceed方法
 5         //从proceed()方法中我们知道dm.interceptor.invoke(this)传过来的参数就是ReflectiveMethodInvocation执行器本身
 6         //这里又直接调用了ReflectiveMethodInvocation的proceed()方法
 7         return mi.proceed();
 8     }
 9     catch (Throwable ex) {
10         if (shouldInvokeOnThrowing(ex)) {
11             invokeAdviceMethod(getJoinPointMatch(), null, ex);
12         }
13         throw ex;
14     }
15 }

第一个拦截器AspectJAfterThrowingAdvice的invoke方法中,直接调用mi.proceed();,从proceed()方法中我们知道dm.interceptor.invoke(this)传过来的参数就是ReflectiveMethodInvocation执行器本身,所以又会执行proceed()方法,拦截器下标currentInterceptorIndex自增,获取下一个拦截器AfterReturningAdviceInterceptor,并调用拦截器中的invoke方法,,此时第一个拦截器在invoke()方法的第七行卡住了,接下来我们看第二个拦截器的执行

AfterReturningAdviceInterceptor

1 @Override
2 public Object invoke(MethodInvocation mi) throws Throwable {
3     //直接调用MethodInvocation的proceed方法
4     Object retVal = mi.proceed();
5     this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
6     return retVal;
7 }

AfterReturningAdviceInterceptor还是直接调用mi.proceed(),又回到了ReflectiveMethodInvocation的proceed()方法中,此时AfterReturningAdviceInterceptor方法卡在第四行,接着回到ReflectiveMethodInvocation的proceed()方法中,拦截器下标currentInterceptorIndex自增,获取下一个拦截器AspectJAfterAdvice,并调用AspectJAfterAdvice中的invoke方法

AspectJAfterAdvice

 1 @Override
 2 public Object invoke(MethodInvocation mi) throws Throwable {
 3     try {
 4         //直接调用MethodInvocation的proceed方法
 5         return mi.proceed();
 6     }
 7     finally {
 8         invokeAdviceMethod(getJoinPointMatch(), null, null);
 9     }
10 }

AspectJAfterAdvice还是直接调用mi.proceed(),又回到了Reflecti

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇如何决定使用 HashMap 还是 TreeM.. 下一篇Java关键字之abstract、final、st..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目