• Spring Aop 源码 (三) (执行过程)


    1.执行入口

    在这里插入图片描述

    在这里插入图片描述

    调用了CglibAopProxy.DynamicAdvisedInterceptor.intercept() 方法

    在这里插入图片描述

    在这里插入图片描述

    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    
    • 1

    这个方法得到一个拦截器链, 是5个增强器封装成MethodInterceptor

    在这里插入图片描述

    然后 mi.proceed() 方法触发拦截器链的方法。

    在这里插入图片描述

    	@Override
    	@Nullable
    	public Object proceed() throws Throwable {
    		// We start with an index of -1 and increment early.
    		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    			return invokeJoinpoint();
    		}
    
    		Object interceptorOrInterceptionAdvice =
    				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
    			// Evaluate dynamic method matcher here: static part will already have
    			// been evaluated and found to match.
    			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 {
    				// Dynamic matching failed.
    				// Skip this interceptor and invoke the next in the chain.
    				return proceed();
    			}
    		}
    		else {
    			// It's an interceptor, so we just invoke it: The pointcut will have
    			// been evaluated statically before this object was constructed.
    			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    最后的一个方法进入了 invoke(this), 进入了拦截器的责任链

    2.进入拦截器责任链

    1. ReflectiveMethodInvocation.proceed() ->
    2. ExposeInvocationInterceptor.invoke(mi) -> currentInterceptorIndex = 1
    3. MethodBeforeAdviceInterceptor.invoke(this) -> advice.before -> mi.proceed -> currentInterceptorIndex = 2
    4. AspectJAfterAdvice.invoke(this) -> return mi.proceed() -> finally invokeAdviceMethod -> currentInterceptorIndex = 3
    5. AfterReturningAdviceInterceptor.invoke(this) -> Object retVal = mi.proceed() -> this.advice.afterReturning(retVal) -> return retVal -> currentInterceptorIndex =4
    6. AspectJAfterThrowingAdvice.invoke(this) -> return mi.proceed() -> catch invokeAdviceMethod
    7. invokeJoinPoint() 执行连接点, 执行目标方法

    在这里插入图片描述

    ExposeInvocationInterceptor, MethodBeforeAdviceInterceptor, AspectJAfterAdvice, AfterReturningAdviceInterceptor, AspectJAfterThrowingAdvice为Filter类

    CglibMethodInvocation 为 FilterChain

    在这里插入图片描述

    2.1 ExposeInvocationInterceptor

    这个拦截器为暴露共享数据

    在这里插入图片描述

    ExposeInvocationInterceptor.invoke()

    先是 invocation.set(mi); 这里的invocation是一个threadLocal, 可以保存共享数据

    在这里插入图片描述

    又进入了ReflectiveMethodInvocation.proceed()

    2.2 MethodBeforeAdviceInterceptor

    前置通知拦截器

    MethodBeforeAdviceInterceptor.invoke()

    在这里插入图片描述

    先是执行了前置通知, 然后返回mi.procced()

    2.3 AspectJAfterAdvice

    后置通知拦截器

    AspectJAfterAdvice.invoke()

    在这里插入图片描述
    返回的是 mi.proceed(), 并进行 invokeAdviceMethod()

    2.4 AfterReturningAdviceInterceptor

    返回通知拦截器

    AfterReturningAdviceInterceptor.invoke()

    在这里插入图片描述

    2.5 AspectJAfterThrowingAdvice

    异常通知

    AspectJAfterThrowingAdvice.invoke()

    在这里插入图片描述

    2.6 invokeJoinPoint()

    执行连接点, 用于执行方法

    在这里插入图片描述

    3.执行顺序

    前置通知 => 目标方法 => 返回通知 => 后置通知

    前置通知 => 目标方法 => 异常通知 => 后置通知

    try{
    	前置通知
    	目标方法
    	返回通知
    }catch(){
    	异常通知
    }finally{
    	后置通知
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    算法系列-链表操作总结
    计算机毕业设计ssm+vue基本微信小程序的今日菜谱系统
    Qt SQL:QSqlField、QSqlRecord、QSqlIndex、QSqlError
    【ccf-csp题解】第11次csp认证-第三题-Json查询超详细讲解
    darknet框架 训练分类模型及测试图片
    Python 面向对象编程之封装的艺术
    行业解密:为什么跨境电商行业都在做社交媒体营销?
    资本频频加码,急于上市的和府捞面有多“疯狂”?
    Go有关方法的笔记(掌握defer与闭包)
    SQL Server 创建表
  • 原文地址:https://blog.csdn.net/qq_43141726/article/details/127433162