Spring3.1.0实现原理分析(十).AOP代理对象执行拦截过程

       大家好,上篇博客讲解了代理对象的创建过程AOP之创建代理对象的过程,今天主要分析下代理对象执行拦截的过程。要说明白执行拦截的过程需要先给大家介绍两个AOP大联盟的接口“MethodInterceptor”和“MethodInvocation”。用张示意图描述下两个接口的关系。
        


       无论是jdk代理对象还是cglib代理对象,它们都持有通知对象列表。通知对象的本质是什么,其实就是实现了AOP大联盟的方法拦截器接口(MethodInterceptor)的对象。为什么这么说呢,是因为或者通知对象直接实现了MethodInterceptor接口(如:前置通知,后置通知),或者通知对象被实现了MethodInterceptor接口的对象引用(如:最终通知, 异常后通知)。总之,通知对象就是拦截器对象。MethodInterceptor接口中只定义了一个方法,Object  invoke(MethodInvocation invocation) ,在这个方法中切入拦截器的处理逻辑。

       代理对象进入回调方法后,首先会获取所有跟被拦截方法匹配的拦截器列表,然后会创建一个实现了AOP大联盟(MethodInvocation) 接口的对象,方法调用对象持有拦截器列表,并调用每个拦截器的invoke(MethodInvocation invocation) 方法,把自身作为实参传入这个方法。MethodInvocation接口中定义了如下几个比较重要的方法。

  • proceed()   ---  执行链中下个拦截器
  • getThis()    ---    获取被代理对象
  • Method getMethod()  ---  获取被拦截的方法对象
  • getArguments()  ---  获取被拦截方法的实参数组
       如上所述,方法调用接口的作用是调用拦截器列表,接口的proceed()方法就是调用拦截器列表的入口,用个图来描述过程更容器理解。简单的说方法代理过程就只有两个步骤:(1).执行所有拦截器; (2).执行拦截理方法。    
       
        
         
        
接下来我们用一个更加具体的例子来表述上图的流程,假设有如下的配置,用户定义了四个通知器。

	<aop:aspect id="logAspect" ref="logAspectBean">
			
		<!-- 定义切入点,指定切入点表达式 -->
		<aop:pointcut id="allMethod" expression="execution(* testaop.com.qiujy.service.*.*(..))"/>
			
		<!-- 应用前置通知 -->
		<aop:before method="before" pointcut-ref="allMethod" /> 
			
		<!-- 应用后置通知 -->
		<aop:after-returning method="afterReturn" pointcut-ref="allMethod"/> 
			
		<!-- 应用最终通知 -->
		<aop:after method="after" pointcut-ref="allMethod"/> 
			
		<!-- 应用异常后通知 -->
		<aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/> 

	</aop:aspect>

当调用accountService代理对象的方法时,进入了回调方法,在回调方法中会获得五个拦截器(有一个是spring自动添加的),有意思的是拦截器的顺序并不是用户定义的通知器顺序,这是因为spring会对拦截器进行排序,五个拦截器的执行顺序如下,

  • ExposeInvocationInterceptor (Spring自动添加的,用于把方法调用对象置入线程安全的缓存)
  • MethodBeforeAdviceInterceptor (前置通知)
  • AspectJAfterThrowingAdvice (异常后通知)
  • AspectJAfterAdvice (最终通知)
  • AfterReturningAdviceInterceptor (后置通知)
完成的执行流程图如下,
 
备注: 上图是执行被拦截方法未出现异常情况下的流程图,如果被拦截方法抛出了异常,则后置通知不会执行,最终通知还是会被调用的,然后再调用异常后通知。  


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值