天天看点

Spring AOP 源码解读

应用场景

公共模块抽象出来,简单的AOP功能编织到模块中

核心技术实现

动态代理,相关的拦截器都配置到了动态对象里

JDK 动态代理

只能代理实现接口的类

invoke里封装了aop的实现

CGLIB 字节码增强技术

可以直接代理类

对callback回调设置中,通过DynamicAdvisedInterceptor拦截器来实现AOP功能的

源码解析

以JDK动态代理为例

JdkDynamicAopProxy

@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			 //如果拦截器链为空,直接调用目标方法
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// We need to create a method invocation...
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				//否则的话,从这里开始调用
				retVal = invocation.proceed();
			}
	}
           

invocation 这个的实现ReflectiveMethodInvocation 这个类

@Override
	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;
		    //匹配这个方法是不是需要拦截,是的话,调用拦截器
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {               //invoke执行拦截器
				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);
		}
	}

           

上面有一个问题,从逻辑来看,是调用了所有的拦截器,再调用目标方法,这个时候,有一个疑问,after 通知不是方法执行了,再调用这个拦截操作嘛,继续往下看

before 拦截器的实现 MethodBeforeAdviceInterceptor

@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
		return mi.proceed();
	}
           

after的实现 AspectJAfterAdvice

@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		finally {
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}
           

我们可以看到before和after有可区别的,before先执行拦截,再调用下一步的拦截,after是一直要调用目标方法执行了之后,才执行这个after的逻辑。这后边是递归的逻辑。