Spring3.1.0实现原理分析(十).AOP之代理对象执行拦截过程
2017-05-28 00:00
676 查看
大家好,上篇博客讲解了代理对象的创建过程《AOP之创建代理对象的过程》,今天主要分析下代理对象执行拦截的过程。
无论是jdk代理对象还是cglib代理对象,它们都持有通知列表对象,而通知对象呢其实就是AOP大联盟的方法拦截器对象(MethodInterceptor)。之所以这么说是因为,或者通知对象直接实现了MethodInterceptor接口(如:前置通知,后置通知),或者通知对象被实现了MethodInterceptor接口的对象引用(如:最终通知, 异常后通知)。总之,通知对象就是拦截器对象。MethodInterceptor接口中只定义了一个方法,Object invoke(MethodInvocation invocation) ,在这个方法中实现拦截器的处理逻辑。
代理对象进入回调方法后,会获取所有跟被拦截方法匹配的拦截器列表,然后调用每个拦截器的invoke方法,切入处理逻辑。这里还需要再介绍一个AOP大联盟的接口,方法调用接口(org.aopalliance.intercept.MethodInvocation) ,细心的读者可能已发现,MethodInterceptor#invoke方法的唯一参数就是这个类型,这个接口及其超接口大致定义了以下几个重要的方法。
proceed() --- 执行链中下个拦截器
getThis() --- 获取被代理对象
Method getMethod() --- 获取被拦截的方法对象
getArguments() --- 获取被拦截方法的实参数组
上述第一个方法proceed(),就是调用拦截器列表的入口,用个图来描述过程更容器理解。简单的说方法代理过程就只有两个步骤:(1).执行所有拦截器; (2).执行被代理方法。
接下来我们用一个更加具体的例子来表述上图的流程,假设有如下的配置,用户定义了四个通知器。
当调用accountService代理对象的方法时,进入了回调方法,在回调方法中会获得五个拦截器(有一个是spring自动添加的),有意思的是拦截器的顺序并不是用户定义的通知器顺序,这是因为spring会对拦截器进行排序,五个拦截器的执行顺序如下,
ExposeInvocationInterceptor (Spring自动添加的,用于把方法调用对象置入线程安全的缓存)
MethodBeforeAdviceInterceptor (前置通知)
AspectJAfterThrowingAdvice (异常后通知)
AspectJAfterAdvice (最终通知)
AfterReturningAdviceInterceptor (后置通知)
完成的执行流程图如下,
备注: 上图是被拦截方法对象未执行异常下的流程图,如果被拦截方法抛出了异常,则后置通知不会执行,最终通知还是会被调用的,然后再调用异常后通知。
无论是jdk代理对象还是cglib代理对象,它们都持有通知列表对象,而通知对象呢其实就是AOP大联盟的方法拦截器对象(MethodInterceptor)。之所以这么说是因为,或者通知对象直接实现了MethodInterceptor接口(如:前置通知,后置通知),或者通知对象被实现了MethodInterceptor接口的对象引用(如:最终通知, 异常后通知)。总之,通知对象就是拦截器对象。MethodInterceptor接口中只定义了一个方法,Object invoke(MethodInvocation invocation) ,在这个方法中实现拦截器的处理逻辑。
代理对象进入回调方法后,会获取所有跟被拦截方法匹配的拦截器列表,然后调用每个拦截器的invoke方法,切入处理逻辑。这里还需要再介绍一个AOP大联盟的接口,方法调用接口(org.aopalliance.intercept.MethodInvocation) ,细心的读者可能已发现,MethodInterceptor#invoke方法的唯一参数就是这个类型,这个接口及其超接口大致定义了以下几个重要的方法。
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 (后置通知)
完成的执行流程图如下,
备注: 上图是被拦截方法对象未执行异常下的流程图,如果被拦截方法抛出了异常,则后置通知不会执行,最终通知还是会被调用的,然后再调用异常后通知。
相关文章推荐
- Spring3.1.0实现原理分析(十).AOP代理对象执行拦截过程
- Spring3.1.0实现原理分析(九).AOP之创建代理对象的过程
- Spring3.1.0实现原理分析(九).AOP创建代理对象的过程
- spring AOP 代理机制、执行过程、四种实现方式及示例详解
- Spring AOP高级——源码实现(3)AopProxy代理对象之JDK动态代理的创建过程
- 黑马程序员--09.动态与代理AOP--06【动态代理实例化的过程升级--目标对象+系统功能的参数化】【实现类似Spring的可配置AOP框架】
- Spring3.1.0实现原理分析(十二).MVC核心类DispatcherServlet初始化过程
- Spring3.1.0实现原理分析(十二).MVC核心类DispatcherServlet初始化过程
- Spring3.1.0实现原理分析(八).获取bean对象
- Spring3.1.0实现原理分析(八).获取bean对象
- Spring Aop原理分析(一) - 建立AopProxy代理对象
- 加强2注解。泛型。类加载器及其委托机制。代理的概念与作用原理,AOP概念。实现AOP功能的封装与配置。类似Spring。
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
- 反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)