Spring之AOP源码解析(上)

这篇具有很好参考价值的文章主要介绍了Spring之AOP源码解析(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Aop相关注解

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

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

@Import注解作用简述

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

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

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

@EnableAsync注解

Spring之AOP源码解析(上),spring,java,后端Spring之AOP源码解析(上),spring,java,后端Spring之AOP源码解析(上),spring,java,后端

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

@EnableTransactionManagement注解

Spring之AOP源码解析(上),spring,java,后端Spring之AOP源码解析(上),spring,java,后端

Spring之AOP源码解析(上),spring,java,后端

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

@EnableAspectJAutoProxy

Spring之AOP源码解析(上),spring,java,后端Spring之AOP源码解析(上),spring,java,后端

@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

Spring之AOP源码解析(上),spring,java,后端

从类的的角度

Spring之AOP源码解析(上),spring,java,后端

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

注解实现动态代理的时机

@EnableAsync注解

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

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

Spring之AOP源码解析(上),spring,java,后端

@EnableTransactionManagement和@EnableAspectJAutoProxy注解

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

Spring之AOP源码解析(上),spring,java,后端Spring之AOP源码解析(上),spring,java,后端Spring之AOP源码解析(上),spring,java,后端

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

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

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

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

Spring之AOP源码解析(上),spring,java,后端

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

我们查看源码PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

Spring之AOP源码解析(上),spring,java,后端

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)

Spring之AOP源码解析(上),spring,java,后端

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

Spring之AOP源码解析(上),spring,java,后端

@EnableAspectJAutoProxy注解未开启设置

Spring之AOP源码解析(上),spring,java,后端

默认的情况下,@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

Spring之AOP源码解析(上),spring,java,后端

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

总结

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

到了这里,关于Spring之AOP源码解析(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【手撕Spring源码】AOP

    AOP 底层实现方式之一是代理,由代理结合通知和目标,提供增强功能 除此以外,aspectj 提供了两种另外的 AOP 底层实现: 第一种是通过 ajc 编译器在 编译 class 类文件时,就把通知的增强功能,织入到目标类的字节码中 第二种是通过 agent 在 加载 目标类时,修改目标类的字节

    2024年02月07日
    浏览(45)
  • Spring AOP 源码分析

    【阅读前提】: 需了解 AOP 注解开发流程:链接 在配置类中添加注解 @EnableAspectJAutoProxy ,便开启了 AOP (面向切面编程) 功能。此注解也是了解 AOP 源码的入口。 【1】 @EnableAspectJAutoProxy 是什么?我们进入注解,查看其源码如下:发现调用 EnableAspectJAutoProxy 类,同时使用 @

    2024年01月16日
    浏览(36)
  • Spring之AOP源码(二)

    书接上文 1. 前文回顾 前面我们已经介绍了AOP的基本使用方法以及基本原理,但是还没有涉及源码层面,这篇文章就深度分析一下SpringAOP的底层源码。 2. 知识点补充 TargetSource 在我们日常的AOP中,被代理对象就是Bean对象,是由BeanFactory给我们创建出来的,但是 Spring AOP中提供了

    2024年01月18日
    浏览(37)
  • 004-Spring AOP源码分析

    CGLIb 动态代理 Spring 统一封装 一个是继承,一个是实现,都有各自适用的场景 但是都是一个实例方法的增强 所以统一封装便于使用 屏蔽了底层的代理工具的切换 抽象了代理方法Advice 不需要再手动调用:被代理类(原型)的方法

    2024年02月14日
    浏览(46)
  • 全面掌握Spring框架:深入解析IOC、AOP、事务管理与注解使用

    探索Spring框架的深层次知识,包括Spring IOC容器的初始化流程、AOP的实现机制、事务管理的细节、循环依赖问题的处理、条件注解的应用、JavaConfig的使用方法、PostProcessor的角色、@Autowired和@Value注解的高级应用,以及${}与#{}的区别。

    2024年03月13日
    浏览(196)
  • 深入解析Spring的IOC与AOP及其在项目中的应用

    在现代的软件开发中,为了提高代码的可维护性、可扩展性以及降低代码的耦合度,使用设计模式和面向切面编程(AOP)成为了程序员们常用的技术手段。Spring作为一个优秀的Java开发框架,提供了IOC和AOP两个核心特性,极大地简化了开发工作。本文将深入探讨Spring的IOC和AO

    2024年02月13日
    浏览(52)
  • Java spring Aop实战

    Spring AOP 1. 实战 1.实战 创建工程和依赖 数据库建表 实体类 Mapper 接口 方法一 方法二 Service 包 接口1: 实现接口 Mapper Mapper 1 Mapper 2 配置xml文件 Xml 1 Xml 2 Spring 配置文件 Mybatis配置文件 测试类 数据库结果 测试2 测试3 不符合业务逻辑,加入事物 头文件 只能在service实现类加 重

    2024年02月15日
    浏览(39)
  • 设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的

    代理模式是一种结构型设计模式,它通过创建一个代理对象来控制对真实对象的访问。这种模式可以用于提供额外的功能操作,或者扩展目标对象的功能。 在代理模式中,代理对象与真实对象实现相同的接口,以便在任何地方都可以使用相同的接口来调用真实对象的方法。这

    2024年01月20日
    浏览(44)
  • 8.1Java EE——Spring AOP

            Spring的AOP模块是Spring框架体系中十分重要的内容,该模块一般适用于具有横切逻辑的场景,如访问控制、事务管理和性能监控等 一、AOP概述         AOP的全称是Aspect Oriented Programming,即面向切面编程。和OOP不同,AOP主张将程序中相同的业务逻辑进行横向隔离,

    2024年02月16日
    浏览(45)
  • Java EE 突击 14 - Spring AOP

    这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架 JavaEE 进阶专栏 Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在 接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点 并且带领大家进行环境的配置 , 让大家真正用好

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包