Spring之AOP源码解析(下)

news2024/10/3 2:27:44

前言

在上一遍文章中,我们主要讲解了ProxyFactory在Spring完成AOP动态代理的过程中发挥的作用。这一篇我们主要讲解这些注解都是如何注入Advisors,然后分析这些Advisors生效的条件

注解都是如何注入Advisor并匹配的

@EnableTransactionManagement注解

我们在之前提到@EnableTransactionManagement注解会注入一个类型为InfrastructureAdvisorAutoProxyCreator的bpp和事务相关的bean

ProxyTransactionManagementConfiguration这个配置类会注入一个类型为BeanFactoryTransactionAttributeSourceAdvisor的Advisor(以bean的方式注入)

InfrastructureAdvisorAutoProxyCreator这个bpp在执行postProcessAfterInitialization方法的时候会查找可以对bean增强的Advisor,如果找到合适的Advisor则会通过进行aop动态代理

目前这些内容我们在之前的文章中都分析了,现在我们重点关注findAdvisorsThatCanApply这个方法 

 当我们不清楚这个Pointcut是什么类型的时候,可以debug看一下

通过debug我们发现Pointcut是@EnableTransactionManagement注解注入的Advisor的匿名内部类

我们查看这个Advisor的类结构

所以这个Pointcut是一个TransactionAttributeSourcePointcut的一个实例对象

我们再查看TransactionAttributeSourcePointcut的类结构

通过以上分析我们小结一下

  • Pointcut的类型为TransactionAttributeSourcePointcut
  • TransactionAttributeSourcePointcut的过滤器类型为TransactionAttributeSourceClassFilter
  • TransactionAttributeSourcePointcut的MethodMatcher为其自身,并且不等于MethodMatcher.TRUE,且不属于IntroductionAwareMethodMatcher

所以最终我们只需要关注TransactionAttributeSourcePointcut的matches是否能匹配成功

TransactionAttributeSourcePointcut#matcheAbstractFallbackTransactionAttributeSource#getTransactionAttribute AbstractFallbackTransactionAttributeSource#computeTransactionAttributeAnnotationTransactionAttributeSource#findTransactionAttribute 
AnnotationTransactionAttributeSource#determineTransactionAttributeSpringTransactionAnnotationParser#parseTransactionAnnotation

综上所述:@EnableTransactionManagement会注入一个类型为BeanFactoryTransactionAttributeSourceAdvisor的Advisor,当spring处理其他普通bean的时候,这个Advisor就会判断这个bean是否满足自己进行增强的条件(bean含有@Transactional注解标注的方法或者类上含有@Transactional注解),如果满足条件,spring在后期就会进行AOP动态代理

@EnableAspectJAutoProxy注解

从前面两篇文章中我们分析得出@EnableAspectJAutoProxy会注入一个类型为AnnotationAwareAspectJAutoProxyCreator的bpp,这个bpp重写了findCandidateAdvisors方法,我们以这个方法为切入口,分析方法是如何增强的

AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisorsBeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisorsReflectiveAspectJAdvisorFactory#getAdvisorsReflectiveAspectJAdvisorFactory#getAdvisorReflectiveAspectJAdvisorFactory#getPointcutAbstractAspectJAdvisorFactory#findAspectJAnnotationOnMethod

 综上所述:@EnableAspectJAutoProxy注入的bpp会额外查找一些符合条件的Advisor,相关条件如下

  1. bean所属的class上含有@Aspect注解
  2. 存在含有@Around,@Before,@After,@AfterReturning,@AfterThrowing标注的方法

查找出的对象被封装成InstantiationModelAwarePointcutAdvisorImpl,接下来的判断逻辑和@EnableTransactionManagement注解是一致的,都是利用AopUtils的canApply方法,我们需要搞清楚下列几个点,其他细节读者可以自行翻阅源码

  1. InstantiationModelAwarePointcutAdvisorImpl的getPointcut方法返回的是AspectJExpressionPointcut
  2. AspectJExpressionPointcut的getClassFilter方法返回的是自身
  3. AspectJExpressionPointcut的getMethodMatcher方法返回的也是自身
  4. AspectJExpressionPointcut的matches方法的匹配细节

小结

@EnableAspectJAutoProxy注入的bpp通过重写findCandidateAdvisors方法,查找出更多的Advisors,每个Advisor都会通过getPointcut方法返回一个Pointcut对象,Pointcut有两个待实现的方法(getClassFilter、getMethodMatcher),spring会先通过getClassFilter方法返回一个Filter来判断目标类是否满足需求,然后再通过getMethodMatcher方法返回一个MethodMatcher对象,如果MethodMatcher对象等于MethodMatcher.TRUE则直接返回true,否则就获取目标类的相关方法,如果存在一个方法满足MethodMatcher的matches方法,则表示这个Advisor可以作用在这个目标类上。如果存在满足条件的Advisor,spring会在后续进行AOP动态代理

@EnableAsync注解

在前文我们分析得出@EnableAsync会注入一个类型为AsyncAnnotationBeanPostProcessor的bpp,我们查看这个类的类结构,获取一些前提条件

1.无参构造函数

作用:将属性beforeExistingAdvisors设置为true 

2.回调方法setBeanFactory

作用:给属性advisor赋值

AsyncAnnotationBeanPostProcessor作为一个bpp,其主要动态代理相关源码在其祖父类的postProcessAfterInitialization方法中,我们来看看相关明细

小提示:在Spring之AOP源码解析(中)这篇文章中我们分析了,如果通过设置的参数,spring最终决定进行jdk动态代理,则会实现SpringProxy,Advised,DecoratingProxy这三个默认接口,否则会实现SpringProxy,Advised这两个默认接口,所以被spring动态代理的类一定实现Advised接口

我们继续查看这个isEligible方法(通过方法调用,获取最里层方法)

我们又看到这个熟悉的canApply方法,判断流程同上,我们需要知道这个advisor的类型为AsyncAnnotationAdvisor,关注相关方法细节就可以了

我将上述三个注解在Spring中的执行时机用时序图展示出来,便于大家更好的理解

说明一下

  1. 步骤1~6顺序可能不固定,但是最终结果是一样的(存在两个bpp和一个advisor)
  2. 步骤13~14是@EnableTransactionManagement(@EnableAspectJAutoProxy)注入的bpp可能产生的两种结果
  3. 步骤17~18是@EnableAsync注入的bpp对于步骤13可能产生的两种结果
  4. 步骤19~20是@EnableAsync注入的bpp对于步骤14可能产生的两种结果

Spring容器启动后,调用代理对象流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1471764.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2实现无感刷新token

🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 📘 引言: &#x1f4…

商家入驻平台怎么让资金自动分配给商家

最近很多上线了多商户电商系统的朋友咨询,我们平台的用户支付后,钱进入了我们的对公账户,怎样让钱在走完流程后,自动进入商家的账户呢?今天商淘云为您分享商户入驻平台自动分配给商家资金的三种方法。 首先是平台应建立…

用户体验设计师如何在 2024抢占先机?

01. 严峻的经济形势和就业市场 我们生活在一个通货膨胀的时代。就从超市抓几个苹果、卷心菜、鸡蛋,看看价格吧!我不得不多次检查收据,因为我简直不敢相信。外出就餐费用上涨了 10-20%,现在 Spotify 和 YouTube 要求收取更高的订阅…

Android 水波纹扩散效果实现

人生只是一种体验,不必用来演绎完美。 效果图 View源码 package com.android.circlescalebar.view;import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.…

2024.2.27 模拟实现 RabbitMQ —— 网络通信设计(客户端)

目录 需求分析 RabbitMQ 客户端设定 ConnectionFactory(连接工厂) Connection(连接) Channel(通道) 针对 客户端 和 服务器 单元测试 需求分析 RabbitMQ 客户端设定 一个客户端可以有多个模块每个模块…

揭秘随身WiFi行业背后的创业故事:格行如何成为领头羊?

第一,聚焦蓝海市场。与其在红海市场与众多对手激烈竞争,不如寻找被忽视的市场需求。格行随身WiFi项目就是一个典型的例子,市场需求量大,比如网约车,外卖员,户外直播,租房党,经常外出…

苹果Vision Pro芯片级拆解:339S01186传感器协处理器,电源管理芯片:343S00627、343S00628、343S00629

2月2日,苹果官方发售Vision Pro后,引发了抢购潮,产品“秒光”,甚至将起售价 3499 美元一度炒到近 9 万元人民币的代购价。 日前知名维修网站iFixit又一次“首拆”了苹果Vision Pro,每一块电路板、每一颗螺丝钉、每一颗…

游泳耳机怎么选?2024年必看的四款王牌游泳耳机推荐!

游泳不仅能有效锻炼身体,还能帮助我们在炎炎夏日中消暑解热。而随着科技的发展,越来越多的智能设备开始融入我们的生活,其中就包括了专门为游泳爱好者设计的游泳耳机。在水下也能享受到音乐的乐趣,无疑为游泳这项运动增添了更多的…

petalinux_zynq7 驱动DAC以及ADC模块之五:nodejs+vue3实现web网页波形显示

前文: petalinux_zynq7 C语言驱动DAC以及ADC模块之一:建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二:petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…

基于AMDGPU-ROCm的深度学习环境搭建

在风起云涌的AI江湖,NVIDIA凭借其CUDA生态和优秀的硬件大杀四方,立下赫赫战功,而另一家公司AMD也不甘示弱,带着他的生态解决方案ROCm开始了与不世出的NVIDA的正面硬钢,"ROCm is the answer to CUDA", AMD官网…

MySQL锁三部曲:临键、间隙与记录的奇妙旅程

欢迎来到我的博客,代码的世界里,每一行都是一个故事 MySQL锁三部曲:临键、间隙与记录的奇妙旅程 前言临键锁的奥秘间隙锁记录锁 前言 在数据库世界中,锁是维护数据完整性的一种关键机制。而MySQL中的临键锁、间隙锁和记录锁则是锁…

2024.2.25 -ElasticSearch 进阶

倒排索引 Elasticsearch的倒排索引机制是通过将文档中出现的词汇与它们所在的文档ID关联起来,实现快速查找包含特定词汇的文档。下面是一个具体的例子来说明倒排索引的工作原理: 假设我们有一个简单的文章集合,包含以下三篇文章&#xff1a…

pytorch 用F.normalization的逆归一化如何操作

逆归一化的时候再把这个数乘回去就行了 magnitude a.norm(p2, dim1, keepdimTrue) # NEW atorch.nn.functional.normalize(a, p2, dim1) a_or a* magnitude # NEW print(a_or) Outputs: tensor([]1,2,3)

springboot网站开发02-接入持久层框架mybatisPlus

springboot网站开发02-接入持久层框架mybatisPlus!经过上一小节内容分享,我们的项目嵌套模式框架搭建好了,下面就是开始编辑具体的业务代码了,我们使用到了持久层框架是mybatisPlus插件。下面是一些具体的植入框架的操作步骤。 第…

【Java程序员面试专栏 算法思维】二 高频面试算法题:二分查找

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,本篇主要聊聊二分查找,包括基础二分,寻找目标值的左右边界,搜索旋转数组以及波峰,以及x的平方根问题,所以放到一篇Blog中集中练习 题目关键字解题思路时间空…

【MySQL面试复习】索引创建的原则有哪些?

系列文章目录 在MySQL中,如何定位慢查询? 发现了某个SQL语句执行很慢,如何进行分析? 了解过索引吗?(索引的底层原理)/B 树和B树的区别是什么? 什么是聚簇索引(聚集索引)和非聚簇索引…

MAC M1 安装mongodb7.0.5 版本

1、进入官网 Download MongoDB Community Server | MongoDBDownload MongoDB Community Server non-relational database to take your next big project to a higher level!https://www.mongodb.com/try/download/community 2、选择版本 3、下载后解压 放到 /usr/local 并修改…

好狄空气能热水器成功上榜2023年消费者心中的十大信赖品牌

随着环保意识的增强和能源消耗的持续关注,空气能热水器以其高效节能、绿色环保的特性赢得了越来越多消费者的青睐。市场上琳琅满目的空气能热水器品牌让消费者在选择时既兴奋又困惑。究竟哪些品牌能在激烈的竞争中脱颖而出,成为消费者心目中的佼佼者呢&a…

MongoDB之客户端工具与核心概念及基本类型篇

MongoDB之客户端工具与核心概念及基本类型篇 文章目录 MongoDB之客户端工具与核心概念及基本类型篇1. MongoDB是什么?1. 关于MongoDB2. 相关客户端工具1. MongoDB Compass2. Studio 3T3. Navicat for MongoDB4. NoSQL Manager for MongoDB Professional 2.MongoDB相关概念2.1 …

RabbitMQ实战学习

RabbitMQ实战学习 文章目录 RabbitMQ实战学习RabbitMQ常用资料1、安装教程2、使用安装包3、常用命令4、验证访问5、代码示例 一、RabbitMQ基本概念1.1. MQ概述1.2 MQ 的优势和劣势1.3 MQ 的优势1. 应用解耦2. 异步提速3. 削峰填谷 1.4 MQ 的劣势1.5 RabbitMQ 基础架构1.6 JMS 二…