Spring之AOP源码解析(上)

news2024/12/22 19:47:53

Aop相关注解

  • @EnableTransactionManagement
  • @EnableAspectJAutoProxy
  • @EnableAsync
  • ...

从注解切入来看看这些注解都干了什么

@Import注解作用简述

注入的类一般继承ImportSelector或者ImportBeanDefinitionRegistrar接口

  • 继承ImportSelector接口:selectImports方法返回的类名会被解析成bean
  • 继承ImportBeanDefinitionRegistrar接口:会在解析阶段执行registerBeanDefinitions方法

Spring解析流程可以看我之前写的博文 《Spring之ConfigurationClassPostProcessor解析流程》重点讲解了@Import等注解是如何解析的

@EnableAsync注解

@EnableAsync注解作用
  • 注入一个类型为AsyncAnnotationBeanPostProcessor的BeanPostProcessor

@EnableTransactionManagement注解

@EnableTransactionManagement注解作用
  • 注入一个类型为InfrastructureAdvisorAutoProxyCreator的BeanPostProcessor
  • 注入事务相关的bean

@EnableAspectJAutoProxy

@EnableAspectJAutoProxy注解作用
  • 注入一个类型为AnnotationAwareAspectJAutoProxyCreator的bpp

@EnableTransactionManagement和@EnableAspectJAutoProxy注解的渊源

从方法的角度

两个类都是通过AopConfigUtils.registerXXX方法注入一个bpp到spring中

注意点:AopConfigUtils的register方法存在三个优先级,如果spring调用了多次register方法,spring会保留优先级最高的bpp(beanName为org.springframework.aop.config.internalAutoProxyCreator)。比如Spring中同时存在@EnableTransactionManagement和@EnableAspectJAutoProxy注解,但因为@EnableAspectJAutoProxy注解注入的bpp的优先级高于@EnableTransactionManagement注解注入的bpp,所以spring只有一个类型为AnnotationAwareAspectJAutoProxyCreator的bean,而不存在类型为InfrastructureAdvisorAutoProxyCreator的bean

相关源码AopConfigUtils#registerOrEscalateApcAsRequired

从类的的角度

两个bpp都继承AbstractAutoProxyCreator,然而Spring动态代理相关的逻辑都是在这个类中处理的,所有我们可以认为@EnableTransactionManagement和@EnableAspectJAutoProxy注解实现动态代理的逻辑是一样的。

注解实现动态代理的时机

@EnableAsync注解

我们从前文中了解到@EnableAsync注解会注入一个类型为AsyncAnnotationBeanPostProcessor的bpp,我们来查看源码

我们通过类的继承关系,关注其祖父类(AbstractAdvisingBeanPostProcessor)的postProcessAfterInitialization方法

@EnableTransactionManagement和@EnableAspectJAutoProxy注解

通过上文的分析,我们主要查看AbstractAutoProxyCreator的postProcessAfterInitialization方法

通过源码,我们得出以下几个结论

  • 几个注解注入的bpp都是通过postProcessAfterInitialization方法进行动态代理
  • Spring是通过ProxyFactory这个类完成动态代理的

Spring是如何解决多个bpp对bean进行处理的顺序问题

我们回过头查看@EnableAsync注解注入的bpp的postProcessAfterInitialization方法

从码义上来说,@EnableAsync注解进行AOP动态代理优先级是比较低的,那Spring是怎么处理,让优先级比较低的bpp稍后执行呢?

我们查看源码PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

Spring会对所有的bpp进行排序,然后按顺序加入到列表中,优先级较高的优先加入,优先处理

这里的比较器使用的是AnnotationAwareOrderComparator,这个比较器大致分成以下步骤

  1. bpp是否继承PriorityOrdered接口,如果都继承PriorityOrdered接口,比较getOrder方法返回的值,值越小,优先级越高
  2. bpp是否继承Ordered接口,如果都继承Ordered接口,比较getOrder方法返回的值,值越小,优先级越高
  3. bpp所属class上是否存在@Order注解,如果存在,比较@Order注解设置的值,值越小,优先级越高
  4. 其他

这里需要注意的是,如果一个bpp继承PriorityOrdered接口,getOrder方法返回的值为100,另外一个bpp继承Ordered接口,getOrder方法返回的值为1,按照第一优先级规则,还是继承PriorityOrdered接口的bpp优先级高

我们查看三个注解相关源码

@EnableAsync注解order默认值是Ordered.LOWEST_PRECEDENCE(Integer.MAX_VALUE)

@EnableTransactionManagement注解order默认值是Ordered.LOWEST_PRECEDENCE(Integer.MAX_VALUE)

@EnableAspectJAutoProxy注解未开启设置

默认的情况下,@EnableAsync和@EnableTransactionManagement注解注入的bpp都继承Ordered接口,并且getOrder方法返回的值都是Ordered.LOWEST_PRECEDENCE(Integer.MAX_VALUE),默认情况下优先级一致,但是@EnableTransactionManagement注解注入bpp的时候,对order值进行了手动设置,保证了如果同时存在@EnableAsync和@EnableTransactionManagement注解的情况下,@EnableTransactionManagement注解注入的bpp进行AOP动态代理,@EnableAsync注解注入的bpp进行增强。如果只存在@EnableAsync注解,则相关bpp进行AOP动态代理

相关源码AopConfigUtils#registerOrEscalateApcAsRequired

这里需要说明一下,虽然@EnableAspectJAutoProxy注解不能指定order值,但是有默认值,默认值也是Ordered.LOWEST_PRECEDENCE(Integer.MAX_VALUE),@EnableTransactionManagement和@EnableAspectJAutoProxy注解从一定程度上来说,这些可以指定的参数是互补的,因为它们进行AOP动态代理的是操作是通过共同父类AbstractAutoProxyCreator完成的

总结

  • @EnableTransactionManagement,@EnableAspectJAutoProxy,@EnableAsync注解都有可能产生AOP动态代理
  • @EnableTransactionManagement,@EnableAspectJAutoProxy注解注入的bpp,都是依靠AbstractAutoProxyCreator这个类完成动态代理的。如果它们同时存在,Spring中只会存在一个优先级更高的bpp。这两个注解指定的参数是互补的,对于特定需求,可以进行扩展
  • 几个注解注入的bpp,都是Spring执行到postProcessAfterInitialization方法阶段,完成AOP动态代理
  • Spring通过registerOrEscalateApcAsRequired方法手动修改了@EnableTransactionManagement,@EnableAspectJAutoProxy注入的bpp的order值,所以执行顺序优先于@EnableAsync注入的bpp
  • 几个注解都是通过ProxyFactory这个类,以策略模式完成AOP动态代理(我们下一篇文章将重点讲解这个类)

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

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

相关文章

后端经典面试题合集

目录 1. Java基础1-1. JDK 和 JRE 和 JVM 分别是什么,有什么区别?1-2. 什么是字节码?采用字节码的最大好处是什么? 1. Java基础 1-1. JDK 和 JRE 和 JVM 分别是什么,有什么区别? JDK 是Java开发工具包&am…

lora网关智慧工厂三色灯安灯状态采集钡铼技术S281

LoRa网关结合钡铼技术S281模块在智慧工厂三色灯安灯状态采集方面具有广泛的应用前景。智慧工厂的安全生产管理对于企业生产经营至关重要,而三色灯安灯是工厂安全生产管理的重要指示灯,通过LoRa无线通信技术和钡铼技术S281模块,可以实现对三色…

网络安全-nc(Netcat)工具详解

经常在反弹shell的时候使用nc命令,但是从来没有了解过,今天翻书看到了,准备记录一下。 nc全称Netcat,是TCP/IP连接的瑞士军刀。哈哈我最喜欢瑞士军刀了。 有一个比较偏的知识点,nc还可以探测目标的端口是否开放&…

【springBoot】springAOP

AOP的概述 AOP是面向切面编程。切面就是指某一类特定的问题,所以AOP也可以理解为面向特定方法编程。AOP是一种思想,拦截器,统一数据返回和统一异常处理是AOP思想的一种实现。简单来说:AOP是一种思想,对某一类事务的集…

B端系统:工作台页面,如何从平庸走向出众

Hi,大家好,我是贝格前端工场,从事8年前端开发的老司机。大家看过很多平庸的工作台页面,但是仔细分析过平庸的表现吗,仔细思考过如何实现出众的效果吗?这篇文章为你解读。 一、工作台页面是什么,…

深信服技术认证“SCCA-C”划重点:深信服超融合HCI

为帮助大家更加系统化地学习云计算知识,高效通过云计算工程师认证,深信服特推出“SCCA-C认证备考秘笈”,共十期内容。“考试重点”内容框架,帮助大家快速get重点知识 划重点来啦 *点击图片放大展示 深信服云计算认证(S…

【STC8A8K64D4开发板】第2-13讲:SPI总线的应用

第2-13讲:SPI总线的应用 学习目的了解SPI总线的结构、特点以及4种通信模式。掌握通过SPI读、写和擦除SPI Flash W25Q128的方法以及代码编写。掌握通过SPI读、写铁电存储器FM25CL64B的方法以及代码编写。 SPI总线原理 SPI是串行外设接口(Serial Peripheral Interfa…

AI 视频 | Stable Video 开放公测了,免部署,免费使用!谁说 4 秒的 AI 视频不香?!

谁说 4 秒的视频不香?2.21 日,Stable Video 开放公测了,不需要自己部署了,直接在网页上就可以生成视频了。 下面这些视频,都是通过 Stable Video Diffusion 生成的,可以先来感受一下: Stable V…

JavaScript的内存管理与垃圾回收

前言 JavaScript提供了高效的内存管理机制,它的垃圾回收功能是自动的。在我们创建新对象、函数、原始类型和变量时,所有这些编程元素都会占用内存。那么JavaScript是如何管理这些元素并在它们不再使用时清理它们的呢? 在本节中,…

LED景观照明灯驱动电路串联、并联和恒流3款方案

LED景观照明灯是现代城市照明中常见的一种灯具。为了保证LED景观照明灯的正常工作,需要设计合适的驱动电路。LED景观照明灯的驱动电路可以采用串联、并联或恒流的方式来设计。 首先,串联驱动电路是指将多个LED灯串联在一起,然后接入电源进行…

不做内容引流,你凭什么在互联网上赚钱?

孩子们放寒假了,待在家里不是看电视,就是拿着手机刷视频,脸上是各种欢快和满足。只是一切换到写作业模式,孩子是各种痛苦表情包,家长则是使出浑身解数,上演亲子大战。可见娱乐常常让人愉悦,而学…

MyBatis-Plus框架(千峰学习笔记)

简介 MyBatis-Plus是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,主要作用 为简化开发、提高效率。 我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。 特性 ● …

XFF伪造 [MRCTF2020]PYWebsite1

打开题目 直接查看源码 看到一个./flag.php 访问一下 购买者的ip已经被记录,本地可以看到flag,那么使用xff或者client-ip伪造一下ip试试 bp抓包 加一个X-Forwarded-For头 得到flag

无线局域网(WLAN)简单概述

无线局域网 无线局域网概述 无限局域网(Wireless Local Area Network,WLAN)是一种短距离无线通信组网技术,它是以无线信道为传输媒质构成的计算机网络,通过无线电传播技术来实现在空间传输数据。 WLAN是传输范围在1…

2、Web攻防-SQL注入-联合查询注入

用途:个人学习笔记,有所借鉴,欢迎指正! 声明:只用于学习交流,点到为止,请勿非法测试。 概念: 联合查询注入:联合注入是回显注入的一种,也就是说联合注入的前…

关于Android下gralloc,hwcompoer以及surface模块的重新认识

关于Android下gralloc,hwcompoer以及surface模块的重新认识 引言 欠债还钱天经地义,知识的债也是如此!这不必须得将我前面欠下来的债给补上!对于任何复杂的知识点,我们都可以采用庖丁解牛的学习方式,一步步…

DSL Query基本语法

DSL Query基本语法 查询的基本语法如下: GET /indexName/_search {"query":{"查询类型":{"查询条件":"条件值"}} }查询所有 GET /indexName/_search {"query":{"match_all":{}} }match查询&#xf…

5分钟让你搞懂什么是Http协议

计算机网络基础课程是计算机专业方向非常重要的一门功课。 所有的互联网都通过网络协议来建立通信连接。 而http协议又是一种无状态的协议,也是工作中最常用的一种基于Web浏览器的网络通信协议。 如何学习http协议?提供三种方法供参考: 第…

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测 目录 分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测分类效果基本描述程序设计参考资…

4.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-模拟游戏登陆器启动游戏并且完成注入

内容参考于:易道云信息技术研究院VIP课 上一个内容:游戏启动流程的分析 码云地址(master 分支):https://gitee.com/dye_your_fingers/titan 码云版本号:bcf7559184863febdcad819e48aaacad9f25d633 代码下…