【Spring - AOP】 --- 目标方法调用流程核心源码解读

el/2023/12/3 2:55:09

文章目录

  • 1 简诉 + 源码跟踪入口
  • 2 目标方法调用流程的骨架 + 获取方法拦截器链
  • 3 链式调用通知方法 --- 责任链模式+递归


1 简诉 + 源码跟踪入口

上篇文章《【Spring - AOP】 — 目标对象增强核心源码解读》解读了spring-aop利用动态代理机制在目标对象创建+初始化过程中对其进行增强的核心源码。对代理模式有所了解的肯定知道,无论是静态代理还是动态代理,只要使用了代理模式,那目标对象里目标方法的调用将不再简简单单只是方法本身。本篇文章将主要探索一下被spring-aop代理的目标对象在被调用时的具体执行流程。
源码的跟踪入口为从IOC容器获取目标对象 —> 并拿着目标对象调用目标方法。如下图所示:
在这里插入图片描述


2 目标方法调用流程的骨架 + 获取方法拦截器链

从IOC容器里获取到的目标对象是被增强后的代理对象,当调用目标对象里的目标方法div时,并不会直接进入div方法,而是会进入到其代理方法intercept。intercept方法里的核心源码如下:
所在类:DynamicUnadvisedExposedInterceptor
在这里插入图片描述


通过通知获取到的当前方法的方法拦截器链如下图所示。可以看到所谓的方法拦截器链就是一个List,且List中方法拦截器的顺序与通知的顺序一致,均为 AfterThrowing -> AfterReturning -> After -> Around -> Before。 — 可以与上文《【Spring - AOP】 — 目标对象增强核心源码解读》进行对比 。
在这里插入图片描述


3 链式调用通知方法 — 责任链模式+递归

如2中图1所示,在拿到通过织入目标方法的通知转换后的方法拦截器链后,spring会拿着该这个方法拦截器链去调用各个通知方法和目标方法,其入口为:
所在类:DynamicUnadvisedExposedInterceptor

// We need to create a method invocation...  //源码第687行
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

那它底层到底是如何调用各个通知方法和目标方法的呢?又是怎样保证各个方法的先后顺序的呢?与我反复提到的通知的顺序和方法拦截器的顺序有没有关系呢?

要解决这些问题肯定还是得深入到源码中去探寻答案。其实说实话这一块的源码我反反复复地已经读了好多好多遍了,但是就是不知道该怎么把他通过文字的形式给展示出来,想了好久最后画了如下这样一幅图。我感觉至少我自己通过这幅图已经可以很清楚地明白spring-aop目标方法调用的核心原理了,当然回答上面几个问题肯定也不在话下了。
proceed()方法所在类ReflectiveMethodInvocation
在这里插入图片描述


上面这幅图我已经上传到github上了— 源码地址:https://github.com/nieandsun/spring-study



http://www.ngui.cc/el/1113711.html

相关文章

【spring事务前置知识】事务的基本特性 + 隔离级别

文章目录1 最近打算2 事务的基本特性3 事务的隔离级别1 最近打算 最近在研究spring事务的源码,因为spring事务的核心流程其实和spring-aop的核心流程很像,所以本想趁热打铁直接写几篇文章总结一下spring事务的核心流程的。但是今天下午突然想到之前在学…

【spring事务前置知识】事务的七大传播行为

文章目录1 简介2 稍微更细致的介绍2.1 第2、3、4种请自行验证2.2 REQUIRES_NEW ---> 父级异常,它可正常提交2.3 PROPAGATION_NESTED ---> 父级异常,它必然回滚;它异常,父级可以不回滚2.4 PROPAGATION_NESTED和PROPAGATION_R…

【spring事务源码学习】--- spring事务三大接口简介

文章目录1 前言2 TransactionDefinition接口3 PlatformTransactionManager接口4 TransactionStatus接口1 前言 spring为管理事务定义了三个接口,分别为 TransactionDefinition — 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则&#xff0…

【spring事务源码学习】--- spring事务核心组件创建过程

文章目录1 通过注解方式配置数据源事务管理器持久层框架2 spring事务核心组件的注册2.1 EnableTransactionManagement注解2.2 TransactionManagementConfigurationSelector类2.3 ProxyTransactionManagementConfiguration --- 三大核心组件2.4 AutoProxyRegistrar --- 事务核心…

【bean的生命周期】--- InstantiationAwareBeanPostProcessor接口简介

文章目录1 InstantiationAwareBeanPostProcessor接口简介2 bean的生命周期总结1 InstantiationAwareBeanPostProcessor接口简介 上篇文章写到spring-aop和spring事务核心后置处理器的前置处理方法入口都为下面的方法: 所在类: AbstractAutowireCapableB…

【spring源码】--- spring-aop和spring事务前置处理方法

文章目录1 简介2 前置处理方法的入口3 AOP的前置处理方法3.1 源码追踪3.1.1 applyBeanPostProcessorsBeforeInstantiation3.1.2 postProcessBeforeInstantiation3.1.3 AOP的shouldSkip方法 --- AOP切面通知解析的入口3.1.4 findCandidateAdvisors3.1.5 buildAspectJAdvisors --…

【spring事务源码学习】--- 目标对象增强核心源码解读

文章目录1 简单回顾2 如何找到适用于当前对象的通知---源码追踪2.1 findAdvisorsThatCanApply --- 入口2.2 AopUtils.findAdvisorsThatCanApply2.3 canApply --- 拿到当前类和当前类的接口,遍历接口和类中的方法看是否有适用于当前bean的通知2.4 matches2.5 getTran…

【spring事务源码学习】--- 目标方法调用流程核心源码解读

文章目录1 简述 源码跟踪入口2 目标方法调用流程核心源码解读2.1 invoke(...) --- 目标方法调用 调用结果返回流程的骨架2.2 proceed方法 --- 责任链递归调用模式的精髓2.3 invoke(this) 方法--- 以事务方式调用目标方法的入口2.4 invokeWithinTransaction --- 事务方式调用目…

【spring事务】 --- exposeProxy属性的作用 --- 同一个对象里方法间调用事务传播行为生效的方法

文章目录1 先看现象2 从源码看一下exposeProxy在事务源码中的逻辑3 解决方式源码地址:https://github.com/nieandsun/spring-study 1 先看现象 有如下代码,调用addUserAndSalary方法,t_user表和t_salary表哪个表里会被插入数据呢?&#xff1…

【bean的生命周期】--- BeanDefinition和BeanFactoryPostProcessor简介

文章目录1 单例业务bean的创建流程简介2 BeanFactoryPostProcessor修改BeanDefinition来干预bean的创建2.1 测试类2.2 BeanDefinition的class属性2.2 BeanDefinition的autowireMode属性2.3 BeanDefinition的constructorArgumentValues属性2.3.1 constructorArgumentValues中的a…