Spring AOP 执行流程原理
AOP 执行流程原理
// 执行目标方法时 会先执行
org.springframework.aop.framework.CglibAopProxy
.DynamicAdvisedIntercepto
.intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object oldProxy = null;boolean setProxyContext = false;Class<?> targetClass = null;Object target = null;try {if (this.advised.exposeProxy) {// Make invocation available if necessary.// 如果需要,使调用可用oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// May be null. Get as late as possible to minimize the time we// "own" the target, in case it comes from a pool...//可能为空。尽量晚到,把我们的时间减到最少//“拥有”目标,以防它来自一个池…target = getTarget();if (target != null) {targetClass = target.getClass();}//获取目标方法拦截器链List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.//检查我们是否只有一个InvokerInterceptor:也就是说,没有真正的建议,只是对目标的反射调用。if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {// We can skip creating a MethodInvocation: just invoke the target directly.// Note that the final invoker must be an InvokerInterceptor, so we know// it does nothing but a reflective operation on the target, and no hot// swapping or fancy proxying.// 我们可以跳过创建方法调用:直接调用目标。注意,最终的调用程序必须是InvokerInterceptor,//所以我们知道它只对目标执行反射操作,没有热交换或花哨的代理。Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = methodProxy.invoke(target, argsToUse);}else {// We need to create a method invocation...// 我们需要创建一个方法调用…<!--CglibMethodInvocation 的.proceed() 方法才是最终实行我们设置的方法通知的增强器接口-->retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}retVal = processReturnType(proxy, target, method, retVal);return retVal;}finally {if (target != null) {releaseTarget(target);}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}
}
CglibMethodInvocation.proceed() 方法的执行过程
org.springframework.aop.framework.ReflectiveMethodInvocation
.proceed() throws Throwable {// We start with an index of -1 and increment early.<!-- currentInterceptorIndex 初始为 -1 只在两种情况下执行该IF代码块中的代码 (1). 方法拦截器链为空的情况下(2). 方法拦截器链执行到最后的情况下爱执行 -->if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {// 利用反射去执行目标方法return invokeJoinpoint();}// 从方法拦截器链中获取一个方法拦截器 从下表 0 递增Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {// Evaluate dynamic method matcher here: static part will already have// been evaluated and found to match.//评估动态方法匹配器这里:静态部分将已经评估并找到匹配。InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {return dm.interceptor.invoke(this);}else {// Dynamic matching failed.// Skip this interceptor and invoke the next in the chain.//动态匹配失败。跳过这个拦截器并调用链中的下一个。return proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.// 它是一个拦截器,所以我们只是调用它:切入点将在构造这个对象之前被静态地计算。<!--当前 MethodInterceptor 调用invoke(this) 方法的执行在下方进行拆解 -->return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}
第一次调用 invoke(this) 方法 拦截器链中第一个拦截器调用
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke (MethodInvocation mi) throws Throwable {MethodInvocation oldInvocation = invocation.get();//设置当前线程的变量invocation.set(mi);try {//再次执行 proceed()方法org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()return mi.proceed();}finally {invocation.set(oldInvocation);}
}
第二次调用 invoke(this) 方法 拦截器链中第二个拦截器调用
// 实为 @AfterThrowing 注解的方法拦截器
org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke (MethodInvocation mi) throws Throwable {try {// 再次调用 proceed 方法return mi.proceed();}catch (Throwable ex) {if (shouldInvokeOnThrowing(ex)) {invokeAdviceMethod(getJoinPointMatch(), null, ex);}throw ex;}}
第三次调用 invoke(this) 方法 拦截器链中第三个拦截器调用
// 实为 @AfterReturning 注解的方法拦截器
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke (MethodInvocation mi) throws Throwable {// 再次调用 proceed 方法Object retVal = mi.proceed();// 在 proceed 方法执行中出现异常后 则直接抛出异常// 正常执行完后 则执行 正常逻辑this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());return retVal;}
第四次调用 invoke(this) 方法 拦截器链中第四个拦截器调用
// 实为 @After 注解的方法拦截器
org.springframework.aop.aspectj.AspectJAfterAdvice.invoke (MethodInvocation mi) throws Throwable {try {// 再次调用 proceed 方法return mi.proceed();}// finally 代码块的出现 确定了目标方法是否正常 都会进行方法执行finally {invokeAdviceMethod(getJoinPointMatch(), null, null);}}
第五次调用 invoke(this) 方法 拦截器链中第五个拦截器调用
// 实为 @Before 注解的方法拦截器
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke (MethodInvocation mi) throws Throwable {//该 invoke 方法会先执行 方法前置通知逻辑this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());// 然后再次执行 proceed 方法return mi.proceed();}
// 此时的 currentInterceptorIndex 指向的是拦截器链的最后一个
// 此次会执行 if 代码块 并通过反射 执行目标方法. 并递归的向上结束方法的执行
proceed() {if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}
Spring AOP 执行流程原理相关推荐
- 【老王读Spring AOP-3】Spring AOP 执行 Pointcut 对应的 Advice 的过程
Spring AOP 执行 Pointcut 对应的 Advice 的过程 前言 版本约定 正文 jdk proxy 是如何执行 Pointcut 对应的 Advice 的? 获取 Advice 链的 ...
- spring aop 执行顺序(@Before @Around @After @AfterReturning @AfterThrowing)
spring aop 执行顺序(@Before @Around @After @AfterReturning @AfterThrowing) 思路 通过单元测试,调用指定方法,验证切面方法执行顺序 代 ...
- Spring MVC执行流程及原理
面试找虐 博主之前每次去面试必问的问题:"讲一下spring mvc的执行流程以及常用组件的作用": 记得第一次和面试官说了大概的流程是这样的:"服务器收到一个请求后会先 ...
- Spring AOP底层实现原理(动态代理)
什么是AOP? AOP(面向切面编程)通过预编译的方式 和 运行期动态代理的方式来实现程序功能统一维护的一种方式,是OOP(面向对象编程)的延续.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业 ...
- Spring AOP的实现原理及应用场景(通过动态代理)
点击关注公众号,利用碎片时间学习 AOP的作用 作用:在不修改源代码的情况下,可以实现功能的增强. 传统的纵向体系代码复用: 横向抽取机制(AOP思想): AOP 思想:基于代理思想,对原来目标对象, ...
- Spring MVC 执行过程原理(请求映射原理、参数处理原理、返回值处理器)
Spring MVC 执行过程分析 文章目录 Spring MVC 执行过程分析 请求映射原理 适配器Adapter 执行目标方法 参数处理器解析器HandlerMethodArgumentResol ...
- Spring Boot 执行流程
2019独角兽企业重金招聘Python工程师标准>>> SpringBoot执行流程 基本概述 SpringBoot将Spring应用的启动流程进行了一个"模板化" ...
- spring aop执行逻辑 奥利给
Spring Aop实例@Aspect.@Before.@AfterReturning@Around 注解方式配置 Spring 方面可以使用下面提到的五种通知工作: 通知 描述 前置通知 在一个方法 ...
- Spring IOC执行流程思维导图
IOC执行流程图 执行流程的各个步骤 参考: IOC执行流程及bean生命周期和作用域总结 Spring IoC 核心流程介绍
最新文章
- 【经典书】随机矩阵理论与无线网络
- DRV8711总是报Pre-driver fault错误原因与处理方法
- Android安全与逆向之Dex动态加载
- DataGrid中加入CheckBox,并实现单选
- HTTP和HTTPS的区别是什么?
- Android在片段之间传递数据
- 4.3.1深度定时器(Timer in Depth)
- Ubuntu18.04下安装配置darknet
- 计算机考试后勤保障管理制度,计算机在高校后勤管理的应用
- 2022年华为杯中国研究生数学建模竞赛A题思路
- JDY-24M钥匙标签使用说明
- 高并发编程之ThreadPool 线程池
- linux 用7zip解压rar,Linux7-rar文件的压缩及解压方法
- win10系统编辑服务器在哪里设置密码,技术编辑处置win10系统忘记登录密码的设置技巧...
- delphi还有人用吗?delphi过时了吗?为什么还有人使用Delphi开发软件?一文说清Delphi的领先一个时代的开发工具DNA
- graph classification and drug discovery
- UTC秒数转换成时间
- python输出一个函数多项式_python实现PolynomialFeatures多项式的方法
- 新近诗作 - 我在找寻什么
- MFC组合框实现多列组合框功能