Spring框架学习[AOP通知以及编程式AOP ](七)

2014-11-24 03:05:50 · 作者: · 浏览: 3
MethodInterceptor getInterceptor(Advisor advisor) { //获取通知器的通知 MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); //将通知封装为方法拦截器 return new MethodBeforeAdviceInterceptor(advice); } }

通过对MethodBeforeAdviceAdapter的源码分析,我们看到通知适配器在获取到通知器的通知后,将通知封装为方法拦截器,我们接下来分析MethodBeforeAdviceInterceptor是如何将通知封装为方法拦截器的。

(2).MethodBeforeAdviceInterceptor封装通知:

MethodBeforeAdviceInterceptor封装通知实现了Spring AOP的织入功能,其源码如下:

[java] view plaincopyprint public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { private MethodBeforeAdvice advice; //拦截器构造方法,初始化通知 public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } //拦截器的回调方法,会在代理对象的方法调用前触发回调 public Object invoke(MethodInvocation mi) throws Throwable { //在目标方法调用之前,先调用前置通知的before方法 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); //继续调用通知拦截链,调用ReflectiveMethodInvocation的proceed方法 return mi.proceed(); } }

通过对MethodBeforeAdviceInterceptor拦截器的源码分析,我们看到,Spring对AOP处理的基本流程:

首先,为目标对象对象创建AOP代理对象,根据AOP配置获取通知器,通知器中持有切入点和通知。

其次,根据通知器中的切入点,获取目标类目标方法的通知,并将通知封装为拦截器,添加到代理拦截链中。

最后,调用目标对象目标方法时,调用AOP代理对象,根据通知在调用目标对象方法时触发调用通知链中通知拦截器的回调方法。

5.方法拦截器:

在4中我们已经分析了MethodBeforeAdviceInterceptor源码,了解到方法拦截器主要作用是根据通知类型在调用目标方法时触发通知的回调,我们接下来分析AfterReturningAdviceInterceptor和ThrowsAdviceInterceptor拦截器的源码,了解对后置通知和异常通知的处理实现:

(1).AfterReturningAdviceInterceptor:

[java] view plaincopyprint public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable { private final AfterReturningAdvice advice; //后置通知拦截器构造方法,初始化通知 public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } //后置通知拦截器回调方法 public Object invoke(MethodInvocation mi) throws Throwable { //调用ReflectiveMethodInvocation的proceed方法,调用通知链 Object retVal = mi.proceed(); //通知链调用最后才调用后置通知的返回之后回调方法 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; } }