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 执行流程原理相关推荐

  1. 【老王读Spring AOP-3】Spring AOP 执行 Pointcut 对应的 Advice 的过程

    Spring AOP 执行 Pointcut 对应的 Advice 的过程 前言 版本约定 正文 jdk proxy 是如何执行 Pointcut 对应的 Advice 的? 获取 Advice 链的 ...

  2. spring aop 执行顺序(@Before @Around @After @AfterReturning @AfterThrowing)

    spring aop 执行顺序(@Before @Around @After @AfterReturning @AfterThrowing) 思路 通过单元测试,调用指定方法,验证切面方法执行顺序 代 ...

  3. Spring MVC执行流程及原理

    面试找虐 博主之前每次去面试必问的问题:"讲一下spring mvc的执行流程以及常用组件的作用": 记得第一次和面试官说了大概的流程是这样的:"服务器收到一个请求后会先 ...

  4. Spring AOP底层实现原理(动态代理)

    什么是AOP? AOP(面向切面编程)通过预编译的方式 和 运行期动态代理的方式来实现程序功能统一维护的一种方式,是OOP(面向对象编程)的延续.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业 ...

  5. Spring AOP的实现原理及应用场景(通过动态代理)

    点击关注公众号,利用碎片时间学习 AOP的作用 作用:在不修改源代码的情况下,可以实现功能的增强. 传统的纵向体系代码复用: 横向抽取机制(AOP思想): AOP 思想:基于代理思想,对原来目标对象, ...

  6. Spring MVC 执行过程原理(请求映射原理、参数处理原理、返回值处理器)

    Spring MVC 执行过程分析 文章目录 Spring MVC 执行过程分析 请求映射原理 适配器Adapter 执行目标方法 参数处理器解析器HandlerMethodArgumentResol ...

  7. Spring Boot 执行流程

    2019独角兽企业重金招聘Python工程师标准>>> SpringBoot执行流程 基本概述 SpringBoot将Spring应用的启动流程进行了一个"模板化" ...

  8. spring aop执行逻辑 奥利给

    Spring Aop实例@Aspect.@Before.@AfterReturning@Around 注解方式配置 Spring 方面可以使用下面提到的五种通知工作: 通知 描述 前置通知 在一个方法 ...

  9. Spring IOC执行流程思维导图

    IOC执行流程图 执行流程的各个步骤 参考: IOC执行流程及bean生命周期和作用域总结​​​​​​​ ​​​​​​​Spring IoC 核心流程介绍

最新文章

  1. 【经典书】随机矩阵理论与无线网络
  2. DRV8711总是报Pre-driver fault错误原因与处理方法
  3. Android安全与逆向之Dex动态加载
  4. DataGrid中加入CheckBox,并实现单选
  5. HTTP和HTTPS的区别是什么?
  6. Android在片段之间传递数据
  7. 4.3.1深度定时器(Timer in Depth)
  8. Ubuntu18.04下安装配置darknet
  9. 计算机考试后勤保障管理制度,计算机在高校后勤管理的应用
  10. 2022年华为杯中国研究生数学建模竞赛A题思路
  11. JDY-24M钥匙标签使用说明
  12. 高并发编程之ThreadPool 线程池
  13. linux 用7zip解压rar,Linux7-rar文件的压缩及解压方法
  14. win10系统编辑服务器在哪里设置密码,技术编辑处置win10系统忘记登录密码的设置技巧...
  15. delphi还有人用吗?delphi过时了吗?为什么还有人使用Delphi开发软件?一文说清Delphi的领先一个时代的开发工具DNA
  16. graph classification and drug discovery
  17. UTC秒数转换成时间
  18. python输出一个函数多项式_python实现PolynomialFeatures多项式的方法
  19. 新近诗作 - 我在找寻什么
  20. MFC组合框实现多列组合框功能

热门文章

  1. 要不起对三队 - alpha冲刺(第三天)
  2. Recovery 模式刷机
  3. Unity2020常用小技巧与设置(建议收藏)
  4. 算法大师:Donald E. Knuth
  5. java中dispose什么意思_java中的dispose()方法
  6. 四色定理已利用计算机证明,地图四色定理的非计算机证明
  7. include、extends用法和区别
  8. 福建省计算机会考成绩6,福建省今年6月会考方案确定 1月会考成绩可查
  9. Excel如何快速删除隐藏表
  10. IDM 6.4.1逆向分析笔记