吃透Spring源码(二十):AOP拦截器链执行过程

例子准备

LogUtil.java

public class LogUtil {
    
    

    private int start(JoinPoint joinPoint){
    
    
        //获取方法签名
        Signature signature = joinPoint.getSignature();
        //获取参数信息
        Object[] args = joinPoint.getArgs();
        System.out.println("log---"+signature.getName()+"方法开始执行:参数是"+Arrays.asList(args));
        return 100;
    }

    public static void stop(JoinPoint joinPoint,Object result){
    
    
        Signature signature = joinPoint.getSignature();
        System.out.println("log---"+signature.getName()+"方法执行结束,结果是:"+result);
    }

    public static void logException(JoinPoint joinPoint,Exception e){
    
    
        Signature signature = joinPoint.getSignature();
        System.out.println("log---"+signature.getName()+"方法抛出异常:"+e.getMessage());
    }

    public static void logFinally(JoinPoint joinPoint){
    
    
        Signature signature = joinPoint.getSignature();
        System.out.println("log---"+signature.getName()+"方法执行结束。。。。。over");

    }

    public Object around(ProceedingJoinPoint pjp) throws Throwable {
    
    
        Signature signature = pjp.getSignature();
        Object[] args = pjp.getArgs();
        Object result = null;
        try {
    
    
            System.out.println("log---环绕通知start:"+signature.getName()+"方法开始执行,参数为:"+Arrays.asList(args));
            result = pjp.proceed(args);
            System.out.println("log---环绕通知stop"+signature.getName()+"方法执行结束");
        } catch (Throwable throwable) {
    
    
            System.out.println("log---环绕异常通知:"+signature.getName()+"出现异常");
            throw throwable;
        }finally {
    
    
            System.out.println("log---环绕返回通知:"+signature.getName()+"方法返回结果是:"+result);
        }
        return result;
    }
}

MyCalculator.java

public class MyCalculator{
    
    
    public Integer add(Integer i, Integer j){
    
    
        Integer result = i+j;
        return result;
    }

    public Integer sub(Integer i, Integer j){
    
    
        Integer result = i-j;
        return result;
    }

    public Integer mul(Integer i, Integer j){
    
    
        Integer result = i*j;
        return result;
    }

    public Integer div(Integer i, Integer j){
    
    
        Integer result = i/j;
        return result;
    }
}

boboAopXmlTest.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
">
    <bean id="logUtil" class="com.bobo.aop.xml.LogUtil"></bean>
    <bean id="myCalculator" class="com.bobo.aop.xml.MyCalculator" ></bean>
    <aop:config>
        <aop:aspect ref="logUtil">
            <aop:pointcut id="myPoint" expression="execution( Integer com.bobo.aop.xml.MyCalculator.*  (..))"/>
            <aop:around method="around" pointcut-ref="myPoint"></aop:around>
            <aop:before method="start" pointcut-ref="myPoint"></aop:before>
            <aop:after method="logFinally" pointcut-ref="myPoint"></aop:after>
            <aop:after-returning method="stop" pointcut-ref="myPoint" returning="result"></aop:after-returning>
            <aop:after-throwing method="logException" pointcut-ref="myPoint" throwing="e"></aop:after-throwing>
        </aop:aspect>
    </aop:config>
</beans>

测试类

public class MyTest {
    
    
    public static void main(String[] args) {
    
    
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/home/bobo");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboAopXmlTest.xml");
        MyCalculator bean = context.getBean(MyCalculator.class);
        bean.add(1, 1);
    }
}

一,执行流程

我们还是用之前xml配置aop方式的例子演示:

public class MyTest {
    
    
    public static void main(String[] args) {
    
    
        // 输出生成的代理类到/home/bobo 目录
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/home/bobo");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("boboAopXmlTest.xml");
        MyCalculator bean = context.getBean(MyCalculator.class);
        bean.add(1, 1);
    }
}

我们调试可以看到,获取到的bean是cglib生成的动态代理对象:

在这里插入图片描述

下面我们先来看一下代理类MyCalculator$$EnhancerBySpringCGLIB$$cfa21dd(我们删除了大量代码,只保留部分与add()方法相关的):

public class MyCalculator$$EnhancerBySpringCGLIB$$cfa21dd extends MyCalculator implements SpringProxy, Advised, Factory {
    
    
    
    private static final Method CGLIB$add$3$Method;
    private static final MethodProxy CGLIB$add$3$Proxy;
  
    static void CGLIB$STATICHOOK1() {
    
    
        CGLIB$emptyArgs = new Object[0];
        Class var0 = Class.forName("com.bobo.aop.xml.MyCalculator$$EnhancerBySpringCGLIB$$cfa21dd");
     
     	var10000 = ReflectUtils.findMethods(new String[]{
    
    "sub", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;", "mul", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;", "div", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;", "add", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;"}, (var1 = Class.forName("com.bobo.aop.xml.MyCalculator")).getDeclaredMethods());

        CGLIB$add$3$Method = var10000[3];
        CGLIB$add$3$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;", "add", "CGLIB$add$3");
    }

    
    final Integer CGLIB$add$3(Integer var1, Integer var2) {
    
    
        return super.add(var1, var2);
    }

    public final Integer add(Integer var1, Integer var2) {
    
    
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
    
    
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (Integer)var10000.intercept(this, CGLIB$add$3$Method, new Object[]{
    
    var1, var2}, CGLIB$add$3$Proxy) : super.add(var1, var2);
    }

    

    public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
    
    
        String var10000 = var0.toString();
        switch(var10000.hashCode()) {
    
    

        case 720618747:
            if (var10000.equals("add(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;")) {
    
    
                return CGLIB$add$3$Proxy;
            }
            break;
        }

        return null;
    }


    public void setCallbacks(Callback[] var1) {
    
    
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
        this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1];
        this.CGLIB$CALLBACK_2 = (NoOp)var1[2];
        this.CGLIB$CALLBACK_3 = (Dispatcher)var1[3];
        this.CGLIB$CALLBACK_4 = (Dispatcher)var1[4];
        this.CGLIB$CALLBACK_5 = (MethodInterceptor)var1[5];
        this.CGLIB$CALLBACK_6 = (MethodInterceptor)var1[6];
    }

    static {
    
    
        CGLIB$STATICHOOK1();
    }
}

我们来看上面代理类的add()方法,会调用到CGLIB$CALLBACK_0intercept()方法。

由上图可知道,CGLIB$CALLBACK_0CglibAopProxy$DynamicAdvisedInterceptor,所以回调到CglibAopProxy$DynamicAdvisedInterceptor类的intercept()方法中:

/**
 * AopProxy的子类。使用Cglib的方法创建代理对象。它持有Advised对象。
 */
@SuppressWarnings("serial")
class CglibAopProxy implements AopProxy, Serializable {
    
    
    
    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
    
    

		private final AdvisedSupport advised;

		public DynamicAdvisedInterceptor(AdvisedSupport advised) {
    
    
			this.advised = advised;
		}

		@Override
		@Nullable
		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    
    
			Object oldProxy = null;
			boolean setProxyContext = false;
			Object target = null;
			TargetSource targetSource = this.advised.getTargetSource();
			try {
    
    
				if (this.advised.exposeProxy) {
    
    
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}

				target = targetSource.getTarget();
				Class<?> targetClass = (target != null ? target.getClass() : null);
				// 获取拦截器通知链
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;

				// 如果没有aop通知配置,那么直接调用target对象的调用方法
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
    
    
					// 如果拦截器链为空则直接激活原方法
					retVal = methodProxy.invoke(target, argsToUse);
				}
				else {
    
    
					// 通过cglibMethodInvocation来启动advice通知
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal;
			}
		}
	}
}

intercept():方法参数:

  • proxy:代理类对象:

在这里插入图片描述

  • method:实际类方法,

在这里插入图片描述

  • args:参数

在这里插入图片描述

  • methodProxy:代理类方法

在这里插入图片描述

intercept()方法主要完成如下步骤:

  1. 获取适合当前方法的拦截器链
  2. 如果拦截器链为空,则直接通过反射执行目标方法
  3. 若拦截器链不为空,则创建方法调用 ReflectiveMethodInvocation 对象的 proceed() 方法启动拦截器链

二,获取拦截器链

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
    
    

	@Override
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass) {
    
    

		// AdvisorAdapterRegistry这个类的主要作用是将Advice适配为Advisor 将Advisor适配为对应的MethodInterceptor
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		Advisor[] advisors = config.getAdvisors();
		// 创建一个初始大小为 之前获取到的 通知个数的集合
		List<Object> interceptorList = new ArrayList<>(advisors.length);
		// 如果目标类为null的话,则从方法签名中获取目标类
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());

		// 循环目标方法匹配的通知
		for (Advisor advisor : advisors) {
    
    
			// 如果是PointcutAdvisor类型的实例
			if (advisor instanceof PointcutAdvisor) {
    
    
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				// 如果提前进行过切点的匹配了或者当前的Advisor适用于目标类
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
    
    
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					boolean match;
					//检测Advisor是否适用于此目标方法
					if (mm instanceof IntroductionAwareMethodMatcher) {
    
    
						if (hasIntroductions == null) {
    
    
							hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
						}
						match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
					}
					else {
    
    
						match = mm.matches(method, actualClass);
					}
					if (match) {
    
    
						// 拦截器链是通过AdvisorAdapterRegistry来加入的,这个AdvisorAdapterRegistry对advice织入具备很大的作用
						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
						// 使用MethodMatchers的matches方法进行匹配判断
						if (mm.isRuntime()) {
    
    
							// 动态切入点则会创建一个InterceptorAndDynamicMethodMatcher对象
							// 这个对象包含MethodInterceptor和MethodMatcher的实例
							for (MethodInterceptor interceptor : interceptors) {
    
    
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
    
    
							// 添加到列表中
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
		}

		return interceptorList;
	}

这里先要拿到之前我们创建好的advisors,在创建的时候已经执行sortAdvisors()方法进行排序,这里拿过来的是已经排好序列的列表:

在这里插入图片描述

下面会去循环遍历每个advisor,判断advisor是否和当前方法add(1,1)匹配,先匹配类,再匹配方法,如果都能匹配就把当前Advisor转化为MethodInterceptor,加入到interceptorList集合里面并返回。

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
    
    
    /**
	 * 此方法把已有的advice实现的adapter加入进来
	 *
	 * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
	 */
	public DefaultAdvisorAdapterRegistry() {
    
    
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}
    
    // 将 Advisor转换为 MethodInterceptor
	@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
    
    
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		// 从Advisor中获取 Advice
		Advice advice = advisor.getAdvice();
		if (advice instanceof MethodInterceptor) {
    
    
			interceptors.add((MethodInterceptor) advice);
		}
		for (AdvisorAdapter adapter : this.adapters) {
    
    
			if (adapter.supportsAdvice(advice)) {
    
    
				// 转换为对应的 MethodInterceptor类型
				// AfterReturningAdviceInterceptor MethodBeforeAdviceInterceptor  ThrowsAdviceInterceptor
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
    
    
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		return interceptors.toArray(new MethodInterceptor[0]);
	}
}

以上源码是把Advisor转化为MethodInterceptor过程:

  • 其中AspectJAfterAdviceAspectJAfterThrowingAdviceAspectJAroundAdvice都实现了MethodInterceptor接口,可以直接强转。
  • AspectJMethodBeforeAdviceAspecrtJAfterReturningAdvice实现了AdvisorAdapter接口,需要从Adapter中获取。

我们可以看一下MethodBeforeAdviceAdapter源码:

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
    
    

	@Override
	public boolean supportsAdvice(Advice advice) {
    
    
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
    
    
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

}

其实从Adapter中也是new了一个MethodInterceptor返回,没有啥区别,为什么要用Adapter呢?其实就是为了方便扩展而已。

最后返回匹配到的拦截器链:

在这里插入图片描述

三,执行拦截器链

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
    
    
    /**
	 * 递归获取通知,然后执行
	 */
	@Override
	@Nullable
	public Object proceed() throws Throwable {
    
    

		// 从索引为-1的拦截器开始调用,并按序递增,如果拦截器链中的拦截器迭代调用完毕,开始调用target的函数,这个函数是通过反射机制完成的
		// 具体实现在AopUtils.invokeJoinpointUsingReflection方法中
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    
    
			return invokeJoinpoint();
		}

		// 获取下一个要执行的拦截器,沿着定义好的interceptorOrInterceptionAdvice链进行处理
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
    
    
			// 这里对拦截器进行动态匹配的判断,这里是对pointcut触发进行匹配的地方,如果和定义的pointcut匹配,那么这个advice将会得到执行
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
    
    
				return dm.interceptor.invoke(this);
			}
			else {
    
    
				// 如果不匹配,那么proceed会被递归调用,知道所有的拦截器都被运行过位置
				return proceed();
			}
		}
		else {
    
    
			// 普通拦截器,直接调用拦截器,将this作为参数传递以保证当前实例中调用链的执行
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}
}

拦截器链的执行过程是按照下标从0--N一个个的拦截器获取并执行的:

1,ExposeInvocationInterceptor

首先执行ExposeInvocationInterceptor,也就是拦截器链中下标为 0 的拦截器,执行其invoke()方法:

public final class ExposeInvocationInterceptor implements MethodInterceptor, PriorityOrdered, Serializable {
    
    
    @Override
	public Object invoke(MethodInvocation mi) throws Throwable {
    
    
		MethodInvocation oldInvocation = invocation.get();
		invocation.set(mi);
		try {
    
    
            // 返回
			return mi.proceed();
		}
		finally {
    
    
			invocation.set(oldInvocation);
		}
	}
}

发现并没有执行什么,直接返回。

此时开始处理拦截器链中下标为 1 的拦截器,也就是AspectJAfterThrowingAdvice

2,AspectJAfterThrowingAdvice

public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {
    
    
    @Override
	public Object invoke(MethodInvocation mi) throws Throwable {
    
    
		try {
    
    
			// 返回
			return mi.proceed();
		}
		catch (Throwable ex) {
    
    
			// 抛出异常
			if (shouldInvokeOnThrowing(ex)) {
    
    
				// 执行异常通知
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			}
			throw ex;
		}
	}
}

执行第一行代码又返回回去了。

此时开始处理拦截器链中下标为 2 的拦截器,也就是AfterReturningAdviceInterceptor

3,AfterReturningAdviceInterceptor

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
    
    
    @Override
	public Object invoke(MethodInvocation mi) throws Throwable {
    
    
		// 返回
		Object retVal = mi.proceed();
		// 返回通知方法
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}
}

执行第一行代码又返回回去了。

此时开始处理拦截器链中下标为 3 的拦截器,也就是AspectJAfterAdvice

4,AspectJAfterAdvice

public class AspectJAfterAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {
    
    
    @Override
	public Object invoke(MethodInvocation mi) throws Throwable {
    
    
		try {
    
    
			// 执行下一个通知/拦截器
			return mi.proceed();
		}
		finally {
    
    
			// 后置通知的方法总是会被执行,原因就在这finally
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}
}

执行第一行代码又返回回去了。

此时开始处理拦截器链中下标为 4 的拦截器,也就是AspectJAroundAdvice

5,AspectJAroundAdvice

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
    
    
    @Override
	public Object invoke(MethodInvocation mi) throws Throwable {
    
    
		ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
		ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
		JoinPointMatch jpm = getJoinPointMatch(pmi);
		return invokeAdviceMethod(pjp, jpm, null, null);
	}
}

下面调用around方法:

protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
    
    
		Object[] actualArgs = args;
		try {
    
    
			ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);

			// 反射调用通知方法
			return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
		}
		
	}

最后调用到Logutil.java的around()方法中:

public class LogUtil {
    
    
    // 省略部分代码...
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
    
    
        Signature signature = pjp.getSignature();
        Object[] args = pjp.getArgs();
        Object result = null;
        try {
    
    
            System.out.println("log---环绕通知start:"+signature.getName()+"方法开始执行,参数为:"+Arrays.asList(args));
            result = pjp.proceed(args);
            System.out.println("log---环绕通知stop"+signature.getName()+"方法执行结束");
        } catch (Throwable throwable) {
    
    
            System.out.println("log---环绕异常通知:"+signature.getName()+"出现异常");
            throw throwable;
        }finally {
    
    
            System.out.println("log---环绕返回通知:"+signature.getName()+"方法返回结果是:"+result);
        }
        return result;
    }
}

我们看到,执行了第一个打引之后,又调用了pjp.proceed(args)方法进行返回,此时我们看到控制台只有第一行打印输出:

在这里插入图片描述

调用了pjp.proceed(args)方法进行返回

此时开始处理拦截器链中下标为 5 的拦截器,也就是最后一个拦截器了MethodBeforeAdviceInterceptor

6,MethodBeforeAdviceInterceptor

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
    
    
    public Object invoke(MethodInvocation mi) throws Throwable {
    
    
		// 执行前置通知的方法
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		// 执行下一个通知/拦截器,但是该拦截器是最后一个了,所以会调用目标方法
		return mi.proceed();
	}
}

执行before()方法,会调用到Logutil的before()方法:

public class LogUtil {
    
    
    private int start(JoinPoint joinPoint){
    
    
        //获取方法签名
        Signature signature = joinPoint.getSignature();
        //获取参数信息
        Object[] args = joinPoint.getArgs();
        System.out.println("log---"+signature.getName()+"方法开始执行:参数是"+Arrays.asList(args));
        return 100;
    }
    
    // 省略部分代码...
}

执行完这个方法之后,控制台会把当前打引出来:

在这里插入图片描述

接下来会执行mi.proceed()方法继续返回:由于已经执行到了最后一个方法了,所以会调用目标方法:

public class MyCalculator{
    
    
    public Integer add(Integer i, Integer j){
    
    
        Integer result = i+j;
        return result;
    }
}

执行完目标方法之后会沿着上面执行流程一个个的返回回去。

7,返回到AspectJAroundAdvice

继续执行LogUtil的around()方法的后面部分:

在这里插入图片描述

执行完之后,控制台会打印出:

在这里插入图片描述

继续返回

8,返回到AspectJAfterAdvice

执行后面finally中的方法:

在这里插入图片描述

会执行到LogUtil中的@After标注的方法:

public class LogUtil {
    
    
    public static void logFinally(JoinPoint joinPoint){
    
    
        Signature signature = joinPoint.getSignature();
        System.out.println("log---"+signature.getName()+"方法执行结束。。。。。over");
    }
}

执行完之后控制台会输出当前打印:

在这里插入图片描述

继续返回

9,返回到AfterReturningAdviceInterceptor

执行后面的方法:

在这里插入图片描述

会执行到LogUtil中的被@AfterReturning标注的方法:

public class LogUtil {
    
    
    public static void stop(JoinPoint joinPoint,Object result){
    
    
        Signature signature = joinPoint.getSignature();
        System.out.println("log---"+signature.getName()+"方法执行结束,结果是:"+result);
    }
}

执行完之后,控制台会输出:

在这里插入图片描述

继续返回

10,返回到AspectJAfterThrowingAdvice

public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {
    
    
    @Override
	public Object invoke(MethodInvocation mi) throws Throwable {
    
    
		try {
    
    
			// 执行下一个通知/拦截器  methodInvocation
			return mi.proceed();
		}
		catch (Throwable ex) {
    
    
			// 抛出异常
			if (shouldInvokeOnThrowing(ex)) {
    
    
				// 执行异常通知
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			}
			throw ex;
		}
	}
}

没有任何异常,所以不输出。

继续返回

11,返回到ExposeInvocationInterceptor

在这里插入图片描述

设置一个空值,然后继续返回

然后执行完毕,以上就是拦截器链的执行过程。

四,总结

用一张图总结拦截器链的执行过程:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u013277209/article/details/114739792
今日推荐