Spring 源码:深度解析AOP源码配置解析

在这里插入图片描述

文章目录

    • 一、 解析AOP配置的入口
      • 1.1 从XML配置到AOP Namespace的解析流程
      • 1.2 分析注解驱动的AOP配置解析流程
    • 二、AOP配置解析的核心流程
      • 2.1 ConfigBeanDefinitionParser 类
      • 2.2 parse()
      • 2.3 parseAdvisor()
      • 2.4 parseAspect()
      • 2.5 parsePointcut()
      • 2.6 createAdvisorBeanDefinition()
      • 2.7 createPointcutDefinition()
    • 三、设计模式
      • 3.1 JDK 动态代理
      • 3.2 CGLIB 代理
      • 3.3 AOP 面向切面
    • 四、实际与应用

一、 解析AOP配置的入口

1.1 从XML配置到AOP Namespace的解析流程

流程解析

  1. 加载配置文件:Spring 应用启动时加载 XML 配置文件。
  2. 解析 XML 配置
    • Spring 解析器会识别 AOP 相关的 XML 元素, 如 <aop:config><aop:aspect><aop:pointcut><aop:before> 等 。
    • 对于使用 AOP 命名空间的配置,Spring 会根据命名空间中定义的 schema 头文件来解析配置。
  3. 创建切面和通知
    • Spring 解析到 <aop:aspect> 元素时,会创建对应的切面,并指定切面的 ID 和引用的 bean
    • 解析<aop:before><aop:after> 等元素时,会创建对应的通知,并指定通知要执行的方法。
  4. 解析切点
    • 当解析到 <aop:pointcut> 元素时,Spring 会创建一个切点,并指定切点的 ID 和表达式。
  5. 应用切面和通知
    • Spring 将切面、切点和通知组合在一起,根据配置中的切点表达式找到目标方法。
    • 然后,Spring 根据配置的通知类型(如前置通知、后置通知等),将通知织入到目标方法的执行流程中。
  6. 创建代理对象
    • 如果目标类被代理,Spring 将根据配置创建代理对象。
    • 对于基于接口的代理,Spring 使用 JDK 动态代理。
    • 对于基于类的代理,Spring 使用 CGLIB 动态代理。
  7. 运行时织入
    • 当应用程序运行时调用目标方法时,代理对象会按照配置织入相应的通知,实现切面功能。
  8. 执行目标方法
    • 最后,Spring 框架会执行被代理的目标方法,并在执行过程中触发配置的通知。

1.2 分析注解驱动的AOP配置解析流程

解析流程

  1. 扫描组件
    • Spring 应用启动时,会扫描指定的包路径下的组件,并解析其中的注解。
  2. 解析切面
    • Spring 容器会检测到被 @Aspect 注解标记的类,并将其识别为切面类。
    • 在切面类中,Spring 解析带有 @Before@After@Around 等注解的方法,这些注解表示切面的通知类型。
  3. 识别切点
    • 切面类中的方法可能带有 @Pointcut 注解,用于定义切点表达式,Spring 会解析这些表达式并创建切点。
  4. 应用通知
    • Spring 解析切面类中带有 @Before@After@Around 等注解的方法,并将其作为通知,与对应的切点关联。
  5. 创建代理对象
    • 对于被代理的目标类,Spring 根据配置情况选择使用 JDK 动态代理还是 CGLIB 动态代理。
    • 如果目标类实现了接口且配置了基于接口的代理,则使用 JDK 动态代理;否则,使用 CGLIB 动态代理。
  6. 运行时织入
    • 当应用程序调用被代理的目标方法时,Spring 框架会根据切面和通知的配置,在方法执行前后织入相应的通知。
  7. 执行目标方法
    • 最终,Spring 框架会执行被代理的目标方法,并在执行过程中触发配置的通知,完成 AOP 的功能。

二、AOP配置解析的核心流程

2.1 ConfigBeanDefinitionParser 类

ConfigBeanDefinitionParser 类是 AOP 配置的 Bean 定义解析器。负责解析 <aop:config> 标签中的配置信息,并将解析结果应用到 Spring 的 Bean 定义中。

主要责任

  1. 解析 AOP 配置信息:解析<aop:config> 标签及其子标签中的配置信息,包括切面定义、通知类型、切点表达式等。
  2. 创建切面相关的 BeanDefinition:根据解析的配置信息,创建切面相关的 BeanDefinition 对象,包括切面、通知等。
  3. 注册 BeanDefinition:将解析得到的 BeanDefinition 注册到 Spring 的 BeanFactory 中,使得这些切面相关的组件可以被容器管理。
  4. 处理切面相关的后处理逻辑:在注册切面相关的 BeanDefinition 之前或之后,可能需要进行一些额外的后处理逻辑,如检查和修正配置、添加其他配置等。

2.2 parse()

根据 <aop:config> 元素及其子元素的配置信息,进行相应的解析和处理,最终将 AOP 相关的配置信息转换为 Spring 容器内部的数据结构。

在这里插入图片描述

2.3 parseAdvisor()

解析<advisor>元素及其子元素的配置信息,并根据解析结果注册相应的 BeanDefinition 到 Spring 容器中。

在这里插入图片描述

2.4 parseAspect()

负责解析 <aspect> 元素及其子元素的配置信息,并根据解析结果注册相应的 BeanDefinition 到 Spring 容器中。

在这里插入图片描述

2.5 parsePointcut()

解析切点元素,获取idexpression属性的值,并根据这些值创建和注册切点定义对象。

在这里插入图片描述

2.6 createAdvisorBeanDefinition()

根据传入的参数创建一个切面通知 Bean 定义对象,并设置相应的属性和构造器参数。

在这里插入图片描述

2.7 createPointcutDefinition()

创建一个切点定义的 Bean,并设置其作用域、合成标记和表达式属性值,然后返回该 Bean 定义对象。

在这里插入图片描述

三、设计模式

3.1 JDK 动态代理

  1. 代理模式:JDK 动态代理是典型的代理模式的应用。
    • 在代理模式中,代理对象充当了客户端和真实对象之间的中介,控制对真实对象的访问。
    • JDK 动态代理中的代理对象就扮演了这样的角色,它通过实现目标对象相同的接口,并持有目标对象的引用,在调用方法时将请求转发给目标对象。
    • 代理模式的使用可以实现对目标对象的访问控制、延迟加载等功能。
  2. 装饰器模式:在 JDK 动态代理中,InvocationHandler 接口扮演了类似于装饰器模式中的装饰器的角色。
    • InvocationHandler 接口包含了对方法的调用处理逻辑,类似于装饰器模式中的装饰器对对象进行额外的包装和处理。
    • 通过 InvocationHandler 的实现类,可以在目标对象的方法调用前后加入额外的逻辑,从而实现类似于装饰器模式的功能。
  3. 工厂模式:JDK 动态代理中的 Proxy 类通过 newProxyInstance 方法动态创建代理对象。
    • newProxyInstance 方法可以看作是一个工厂方法,根据传入的类加载器、接口数组和 InvocationHandler 对象动态产生代理对象。
  4. 反射模式:JDK 动态代理的实现基于 Java 的反射机制。
    • 通过反射机制可以在运行时获取并操作类、对象、接口等信息。
    • 代理对象在接收到方法调用时,利用反射机制将调用转发给 InvocationHandler 中的 invoke 方法进行处理,从而实现代理的功能。

3.2 CGLIB 代理

  1. 委托模式:CGLIB代理通过生成目标类的子类来实现代理。
    • 在子类中重写目标方法并调用代理逻辑。
    • 这种方式类似于委托模式,即将目标对象的功能委托给代理对象来实现。
  2. 模板方法模式:CGLIB生成的代理类通常使用了模板方法模式。
    • 在生成的子类中定义模板方法,并在模板方法中调用用户定义的回调方法(如代理逻辑)。
    • 这样设计使得用户能够通过继承代理类并重写回调方法来定义自己的代理逻辑。
  3. 工厂模式:CGLIB代理通常涉及到代理类的创建过程,可看作是工厂模式的应用。
    • CGLIB通过字节码生成技术在运行时动态生成代理类,为客户端提供了一种动态创建代理对象的方式,符合工厂模式的特点。
  4. 策略模式:CGLIB代理允许用户通过定义回调方法来实现代理逻辑,这样的设计类似于策略模式的应用。
    • 用户可以根据需要定义不同的代理策略(即不同的回调方法),并将其传递给CGLIB来生成相应的代理类。
  5. 反射模式:CGLIB的实现基于对类的字节码进行操作,这样的设计类似于反射模式的应用。
    • CGLIB使用了反射来生成代理类的字节码,并在运行时加载和处理这些字节码,从而实现代理功能。

3.3 AOP 面向切面

  1. 代理模式:AOP 中的代理对象充当了目标对象和横切逻辑之间的中介,控制对目标对象方法的访问。
    • 通过代理模式,AOP实现了横切逻辑的注入,并在目标方法执行前后执行额外的逻辑,如日志记录、性能监控等。
  2. 装饰器模式:AOP 中的横切逻辑类似于装饰器模式中的装饰器。
    • 在目标方法的执行前后加入额外的逻辑。
    • AOP框架在运行时动态地将这些横切逻辑织入到目标对象的方法调用中,类似于装饰器模式中的装饰器对对象进行包装和处理。
  3. 观察者模式:AOP中的切面可以理解为观察者,观察目标对象方法的执行,并在特定的切点上执行相应的逻辑。
    • 切面可以订阅特定的切点,当这些切点被触发时,切面就会执行相应的逻辑,类似于观察者模式中的观察者对目标对象的变化做出反应。
  4. 工厂模式:AOP框架通常使用了工厂模式来创建代理对象。
    • 通过配置文件或注解等方式定义切面和切点,AOP框架会根据这些定义动态地创建代理对象,并将横切逻辑织入到目标对象的方法调用中,从而实现面向切面编程的功能。
  5. 模板模式:AOP框架中的代理对象通常使用了模板模式。
    • AOP框架提供了一种模板化的方式来定义横切逻辑,并在执行目标方法前后调用相应的模板方法,这样的设计使得用户能够通过继承并重写模板方法来定义自己的横切逻辑。

四、实际与应用

如何在实际项目中应用 Spring AOP 实现事务管理

假设有一个 简单的订单管理系统,包含订单服务和相关的实体类。希望在创建订单的过程中实现事务管理,即要么全部成功,要么全部失败。

  1. 添加依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 其他依赖 -->
  1. 定义订单实体类 Order 。
/*** @Entity: 这个注解表明这是一个 JPA 实体类* */
@Entity
public class Order {/*** @Id: 表示该字段是实体类的主键* @GeneratedValue: 指定了主键的生成策略 -> GenerationType.IDENTITY:主键值会自动增加*/@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String orderNumber;private double amount;// Getters and setters
}
  1. 定义订单服务类 OrderService,并添加创建订单的方法。
/*** 在方法上添加 @Transactional 注解,Spring AOP 可以在方法执行前后自动管理事务的开启、提交和回滚*/
@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Transactionalpublic void createOrder(String orderNumber, double amount) {Order order = new Order();order.setOrderNumber(orderNumber);order.setAmount(amount);orderRepository.save(order);}
}
  1. 配置事务管理:在 Spring Boot 主类上添加 @EnableTransactionManagement 注解,启用事务管理。
@SpringBootApplication
@EnableTransactionManagement
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

攀登顶峰,这种奋斗的本身就足以充实人的心

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

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

相关文章

算法每日一题(python,2024.05.29) day.11

题目来源&#xff08;力扣. - 力扣&#xff08;LeetCode&#xff09;&#xff0c;简单&#xff09; 解题思路&#xff1a; 法一&#xff1a;切片函数法 直接用python中的切片函数直接解决 法二&#xff1a;交换法 从俩头开始交换字符串的数字&#xff0c;若为奇数&#xff…

具有激情的技术管理者才是优秀的领导者

与其他类型的管理者相比&#xff0c;技术管理者更要具有激情&#xff0c;有激情的技术领导者才能影响和感染团队成员&#xff0c;实现团队的目标。 激情能够带领团队走出阴霾。在所有人都觉得没有希望而选择放弃的时候&#xff0c;有激情的管理者能够带领团队面对困难&#xf…

GITLAB常见问题总结

Troubleshooting GitLab Pages administration (FREE SELF) 原文地址 stage: Plan group: Knowledge info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/…

STM8单片机变频器设计

变频调速技术是现代电力传动技术的重要发展方向,而作为变频调速系统的核心—变频器的性能也越来越成为调速性能优劣的决定因素,除了变频器本身制造工艺的“先天”条件外,对变频器采用什么样的控制方式也是非常重要的。随着电力电子技术、微电子技术、计算机网络等高新技术的…

Kompas AI:智能生活的开启者

引言 在现代社会&#xff0c;**人工智能&#xff08;AI&#xff09;**已经深刻地影响了我们的生活和工作。无论是智能家居、自动驾驶&#xff0c;还是医疗诊断&#xff0c;AI的应用无处不在。而在众多AI平台中&#xff0c;Kompas AI 作为一个先进的对话式AI平台&#xff0c;通过…

R语言数据分析-针对芬兰污染指数的分析与考察

1. 研究背景及意义 近年来&#xff0c;随着我国科技和经济高速发展&#xff0c;人们生活质量也随之显著提高。但是&#xff0c; 环境污染问题也日趋严重&#xff0c;给人们的生活质量和社会生产的各个方面都造成了许多不 利的影响。空气污染作为环境污染主要方面&#xff0c;更…

【漏洞复现】海康威视综合安防管理平台 orgManage/v1/orgs/download 任意文件读取漏洞

0x01 产品简介 海康威视综合安防管理平台是一套“集成化”、“智能化”的平台,通过接入视频监控、一卡通、停车场、报警检测等系统的设备。海康威视集成化综合管理软件平台,可以对接入的视频监控点集中管理,实现统一部署、统一配置、统一管理和统一调度。 0x02 漏洞概述 海康…

7-8 矩阵字符

给定一个仅包含小写字母的字符串S,用这些字符恰好排成一个n行m列的矩阵(m≥n)&#xff0c;请找出所有符合要求的矩阵中最接近于正方形的那个矩阵。然后从第一列开始&#xff0c;逐列按照从上到下的顺序输出矩阵中的字符。 例如&#xff1a;S "abcdefgh"。按要求m≥…

动态规划-求买卖股票所能获得的最大收益(hard)

一、问题描述 二、解题思路 1.先看有哪几个可变参数&#xff1a; (1).当前第几天 nowday(范围&#xff1a;0->n-1) (2).剩余交易次数 restTime(范围&#xff1a;k->0) (3).当天可买入还是可卖出 isnowHold(0 表示当前未持有可买入&#xff0c;1 表示当前持有可卖出) 2.…

WIN10环境下xposed环境搭建

禁止拿来干坏事&#xff0c;仅做学习为目的 环境需求 1.夜神模拟器7.1 2.Android stdio 2022.3.1 3. Adb环境配置 具体实现 1.安装xposed 打开可一键安装&#xff0c;重启 2.连接虚拟机 adb connect 127.0.0.1:620013.打开as,进入project 4.在lib下添加准备好的jar包 …

AD软件底层丝印反转

快捷键VB&#xff0c;翻转后底部视图所有显示就正常了&#xff0c;当底层确认之后再按VB就回到正常状态。 否则你就看到一个镜像的丝印。 快捷键VB后 注意&#xff0c;经过VB反转BOTTOM后TOP层的丝印变镜像翻转了。 设计完毕后调整过来即可。

高级优化理论与方法(十四)

高级优化理论与方法&#xff08;十四&#xff09; Non-linear Constrained OptimizationKKT-Theorem(FONC)SONCDefinitionSOSCExample 1Example 2 Convex Optimization ProblemsDefinitionLemmaTheoremLemmaExampleTheorem TheoremExample DefinitionTheoremLemmaCorollaryLemm…

查询语言:ClickHouse的SQL基础与特点

1.背景介绍 查询语言&#xff1a;ClickHouse的SQL基础与特点 作者&#xff1a;禅与计算机程序设計艺術 1. 背景介绍 1.1 ClickHouse简介 ClickHouse是Yandex开源的一个高性能分布式 column-oriented DBSMS (Column-based Distributed SQL Management System)&#xff0c;它…

怎么下载 jar 包

一、在Maven仓库里面下载 Maven仓库 网址&#xff1a;https://mvnrepository.com/ 二、搜索需要的 jar 包&#xff08;以 druid 为例&#xff09; 三、找到 druid jar包&#xff0c;点进去 四、找到自己需要的版本&#xff0c;点进去 五、 点 jar 下载

【漏洞复现】SpringBlade tenant/list SQL 注入漏洞

0x01 产品简介 SpringBlade ,是一个由商业级项目升级优化而来的 SpringCloud 分布式微服务架构、SpingBoot 单体式微服务架构并存的综合型项目。 0x02 漏洞概述 SpringBlade 后台框架 /api/blade-system/tenantist路径存在SQL注入漏洞&#xff0c;攻击者除了可以利用 SQL 注…

【深度学习在计算机视觉中的应用:塑造机器的视觉智能】

文章目录 前言深度学习在计算机视觉中的关键应用图像分类示例&#xff1a;使用卷积神经网络分析代码结论 前言 计算机视觉是一个模仿人类视觉感知能力的领域&#xff0c;它使计算机能够从图像和视频中识别、处理和理解视觉信息。深度学习的兴起极大地推动了计算机视觉技术的发…

关于网络编程

目录 1、InetAdress类 2、Socket套接字 3、UDP数据报套接字编程 &#xff08;1&#xff09;DatagramSocket 类 &#xff08;2&#xff09;DatagramPacket类 &#xff08;3&#xff09;处理无连接问题 UdpEchoServer.java UdpEchoClient.java 4、TCP流套接字编程 &…

WHAT - AI 工具推荐

AI 资源门户 AiMapProAI工具集 设计师 了解AIGC前沿技术&#xff0c;AI设计师公开课 图片 1. 常用 生成矢量图的 AI 绘图工具 - recraftlogo 生成 - logoai抠图 - 打开图像以去除背景adobe photoshop 网页版 - 支持生成式AI 2. Midjourney Midjourney Prompt Generator…

为什么我觉得C/C++好简单?

有几个可能的原因解释为什么您觉得C/C简单。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 适应性&#xff1a;如果…

气膜建筑的膜材更换与维护—轻空间

气膜建筑作为一种新型建筑形式&#xff0c;因其独特的优势和广泛的应用而受到关注。膜材是气膜建筑的核心组成部分&#xff0c;其质量和维护状况直接影响到建筑的使用寿命和性能。本文将详细探讨气膜建筑的膜材使用寿命、维护及更换的重要性。 膜材的使用寿命 气膜建筑的膜材通…