Advice通知,所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

(1)BeforeAdvice、AfterAdvice:SpringAOP自定义的通知,用于拦截的方法之前或者之后,继承了AOP联盟的通知接口Advice。 

(2)MethodBeforeAdvice、AfterReturningAdvice:仍然是SpringAOP自己的接口设计 

MethodBeforeAdvice:继承了BeforeAdvice,但是BeforeAdvice只有这一个子类,即目前的SpringAOP只能实现对方法的拦截,不能实现对字段的拦截这种更精细的拦截,而Aspectj本身是支持这种拦截的。 

引入了接口方法: void before(Method method, Object[] args, Object target) throws Throwable;即在调用target的method方法之前我们可以做一些事情。 

AfterReturningAdvice:继承了AfterAdvice,引入了接口方法: void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;必然比上面的

before方法多了一个返回值Object returnValue,使得我们可以对返回值进行操作和修改。 

(3)AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice、AspectJAfterAdvice、AspectJAroundAdvice:上面的接口设计好了,就需要来实现它,这几个类都是借助于Aspectj来完成上述的功能。 

前置通知:AspectJMethodBeforeAdvice

后置通知:AspectJAfterAdvice


异常通知:AspectJAfterThrowingAdvice

最终通知:AspectJAfterReturningAdvice


环绕通知:AspectJAroundAdvice

Spring Aop源码学习--Advice通知_spring



MethodInterceptor方法拦截器MethodInterceptor这一重要接口,所有的advice都要最终转化成MethodInterceptor,它的invoke接口方法包含了拦截器要执行的内容及执行的顺序。 


MethodInterceptor:是AOP联盟定义的接口,引入重要方法Object invoke(MethodInvocation invocation) throws Throwable;MethodInvocation invocation则像由一个个MethodInterceptor组成的链条(后面会进行说明),每次执行MethodInterceptor的invoke方法实现一个拦截,同时要把链条给它,以便继续执行下一个MethodInterceptor。 

总结:对于advice构建成MethodInterceptor,分两种情况 

(1)advice本身就实现了MethodInterceptor,如AspectJAfterAdvice、AspectJAfterThrowingAdvice、AspectJAroundAdvice。 

(2)那些没有实现MethodInterceptor的advice,如MethodBeforeAdvice、AfterReturningAdvice,则会进一步转换成MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor。这一过程又是采用适配器模式,适配器模式还是很常见的,所以要学会然后好好利用,如下面所示: 

Spring Aop源码学习--Advice通知_spring_02


AdvisorAdapter:Advisor适配器,用来创建MethodInterceptor。

Spring Aop源码学习--Advice通知_spring_03


AfterReturningAdviceAdapter用来生成AfterReturningAdviceInterceptor

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

MethodBeforeAdviceAdapter用来生成MethodBeforeAdviceInterceptor


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

ThrowsAdviceAdapter用来生成ThrowsAdviceInterceptor

@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
return new ThrowsAdviceInterceptor(advisor.getAdvice());
}

接下来我们通过源码分析

MethodInterceptor是如何实现拦截执行的,每次执行 MethodInterceptor的invoke方法实现一个拦截,同时要把链条给它,以便继续执行下一个MethodInterceptor。

(1)AspectJAfterAdvice:在mi.proceed()之后执行,如下: 

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


(2)AspectJAfterThrowingAdvice:在mi.proceed()之后执行异常,如下:

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
//出现异常后执行
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}


(3)MethodBeforeAdviceInterceptor:在mi.proceed()之前执行,如下:

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

(4)AfterReturningAdviceInterceptor :在mr.proceed执行获取返回值之后进行执行,如下:

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();//执行之后运行
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}



总结:简单来说Advice提供了各种通知,通过拦截执行器来实现了5种通知的执行。