当AOP增强后的代理Bean执行切入点方法时会进入JdkDynamicAopProxy的invoke方法
1.首先看下切面类,当前有前置、后置、完成后置、异常四种通知。Spring解析时会解析为四个通知器(advisor)
@Aspect
@Component
public class MyAspect {
@Pointcut(value = "execution(* *..service.*.*(..))")
public void p1(){
}
@Before(value = "p1()",argNames = "aa")
public void before(JoinPoint aa){
for (Object arg : aa.getArgs()) {
System.out.println(arg);
}
System.out.println("前置横切逻辑通知");
}
@After(value = "p1()")
public void after(){
System.out.println("后置横切逻辑通知");
}
@AfterReturning(value = "p1()" ,returning="result")
public void afterReturn(Object result){
System.out.println(result);
System.out.println("正常返回时横切逻辑通知");
}
@AfterThrowing(value = "p1()",throwing = "throwable")
public void Exception(Throwable throwable){
System.out.println(throwable.fillInStackTrace());
System.out.println("发生异常时横切逻辑通知");
}
}
2.当代理类的切点方法执行时进入invoke方法
JdkDynamicAopProxy.class
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
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);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
3.进入invocation.proceed()方法,获取第i个通知器,并执行其定义好的invoke方法,此处每个invoke方法都有一个ReflectiveMethodInvocation参数,传入当前线程在步骤2中创建的方法执行器MethodInvocation,方便通知器完成各自逻辑后回调MethodInvocation#proceed方法进入下个通知器逻辑。
ReflectiveMethodInvocation.class
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
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 {
return proceed();
}
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
4.下面按执行顺序依次进入五个通知器方法
4.1 ExposeInvocationInterceptor通知器Spring自带的
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
4.2 ExposeInvocationInterceptor执行完逻辑后回调方法执行器的proceed()方法又回到步骤3中进入第二个通知器AspectJAfterThrowingAdvice
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
4.3AspectJAfterThrowingAdvice执行完逻辑后回调方法执行器的proceed()方法又回到步骤3中进入第三个通知器AfterReturningAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
4.4AfterReturningAdviceInterceptor执行完逻辑后回调方法执行器的proceed()方法又回到步骤3中进入第四个通知器AspectJAfterAdvice
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
4.5 AspectJAfterAdvice执行完逻辑后回调方法执行器的proceed()方法又回到步骤3中进入第四个通知器MethodBeforeAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}