Spring Aop源码学习--Advice通知

Posted 归田

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Aop源码学习--Advice通知相关的知识,希望对你有一定的参考价值。

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




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。这一过程又是采用适配器模式,适配器模式还是很常见的,所以要学会然后好好利用,如下面所示: 


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


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种通知的执行。



以上是关于Spring Aop源码学习--Advice通知的主要内容,如果未能解决你的问题,请参考以下文章

Spring 学习——Spring AOP——AOP配置篇Advice(无参数传递)

Spring AOP通知实例 – Advice

spring学习 注解AOP 通知传递参数

spring源码学习spring的AOP面向切面编程的实现解析

Spring笔记07(Spring AOP的通知advice和顾问advisor)

#展望我的2022Flag#Spring框架使用AspectJ实现AOP前置通知学习笔记