【Spring6源码・AOP】AOP源码解析

news2024/12/28 18:54:22

上一篇《【Spring6源码・AOP】代理对象的创建》,我们知道了代理是如何创建的,那么它又是如何工作的呢?

创建完代理对象之后,最终,会真正的执行我们的目标方法,但是步入该方法,会进入cglib代理类的拦截方法。

在这里插入图片描述

进入cglib代理类
在这里插入图片描述

进入拦截方法之后,首先获取拦截器链, 这里面就是我们切面类中定义的前置 后置 环绕的配置,还有一个是默认的。

在这里插入图片描述
看看是如何获取这些拦截器的,先从缓存里取,如果缓存没有调用getInterceptorsAndDynamicInterceptionAdvice() 方法去获取。
在这里插入图片描述

步入getInterceptorsAndDynamicInterceptionAdvice() 方法,首先获取切面相关的通知配置,初始化拦截器List集合。

在这里插入图片描述

紧接着在这个方法中,对advisors数组,进行循环遍历进行处理。

首先判断当前方法是否和我们切点中配置的方法相匹配。

在这里插入图片描述
如果匹配,则调用registry.getInterceptors方法将 advice 转化为 intercepter。

让我们看看是如何进行转换的,步入registry.getInterceptors方法,初始化拦截器集合,获取Advice【切面相关的配置】,对适配器进行循环,找到符合的拦截器,然后加入我们初始化好的拦截器List集合中,

private final List<AdvisorAdapter> adapters = new ArrayList<>(3);

如果适配器支持解析出来的advice,那么就会将advisor解析成拦截器,就 是86行的代码,adapter.getIntercepter();
在这里插入图片描述

步入adapter.getIntercepter()方法,每个适配器都会对应自己的拦截器。

在这里插入图片描述

得到拦截器之后,放到缓存中,以供下次使用。

在这里插入图片描述

就此,得到了想要的拦截器chain,最后创建CglibMethodInvocation对象,调用该对象的proceed()方法。
在这里插入图片描述
来看一下CglibMethodInvocation的proceed()方法。

在这里插入图片描述
最终来到如下方法,最后调用184行代码,去调用该拦截器:
在这里插入图片描述

步入proceed()方法:

在这里插入图片描述

调用其父类的proceed()方法:
在这里插入图片描述

调用invoke()方法:
在这里插入图片描述

继续…

在这里插入图片描述

go on…太深了
在这里插入图片描述

最后将我们所有的目标方法封住成一个Object数组作为参数:

在这里插入图片描述

这里首先通过反射机制,将方法设置为可以访问。
在这里插入图片描述

最后去调用invoke()方法:
在这里插入图片描述

invoke():
在这里插入图片描述
最终,根据我们的切面以及目标方法进行相关处理。

最后通过invoke0( )方法去调用本地方法,进而去调用切面中around()方法。

在这里插入图片描述

调用aroud方法
在这里插入图片描述

p.proceed() 方法前的操作都执行完之后,会调用该方法。
在这里插入图片描述

步入该proceed方法。。。省略若干调用。。。最终调用invoke()方法:
在这里插入图片描述
注意一下这里:this.interceptorsAndDymamicMethodMatchers这个缓存实际上存放了所有的和切面相关的拦截器,并且在初始化的时候是按排序存放的:环绕的前置、before、【目标方法】after、环绕的后置。

并且每次从缓存中取的时候,索引都会+1,这样就可以递归该方法,而且可以按顺序调用每一个拦截器。

在这里插入图片描述

不信你看看
在这里插入图片描述

所以,我们该执行before这个拦截器了,进入上图的invoke()方法。

在这里插入图片描述
步入before()方法,最终又到了这,设置方法的访问权限,再调用invoke。

在这里插入图片描述
最后还是调用了本地方法,去调用了切面的before方法。

在这里插入图片描述
在这里插入图片描述
完成了before的操作,才开始目标方法的调用:

在这里插入图片描述
其实到这里,我们就应该知道,下一步应该会调用after这个拦截器,在这个拦截器真正执行之前,会调用目标方法:

咱们来看看吧,截图真麻烦…

如果此时当前拦截器索引和缓存中的 size-1 相等,那么就会执行下面的方法:
在这里插入图片描述

步入该方法:

设置方法访问权限,然后invoke
在这里插入图片描述

通过反射去调用我们的目标方法:

然后就调用了我们的目标方法:在这里插入图片描述

最后执行finally中的方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后调用本地方法。
在这里插入图片描述
在这里插入图片描述

调用after方法。不行了,我得去吃饭了,妈妈叫我吃饭了,呜呜呜,你们自己看看,挺简单的。🆒溜了。。。。
在这里插入图片描述

退出after的拦截器,before拦截器。。。。。。。。。

在这里插入图片描述
最后回到around方法中,继续执行后面的操作:

在这里插入图片描述

最后结束around拦截器:

在这里插入图片描述
至于这个返回值,返回的是目标方法的。

在这里插入图片描述

在这里插入图片描述
好了,好了,累死了,好像有个问题没有写,就是三级缓存相关的,明天吧,专门给三级缓存写一篇。

祝大家开心,爱你们。♥♥♥

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

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

相关文章

ET框架关于opCode的理解

因为所有的网络消息在发送时候格式都是这样 对于用Protobuf定义的每一消息类型class&#xff0c;都需要定义一个对应消息头code在发送的时候&#xff0c;先将消息体进行序列化&#xff0c;再将code进行序列化&#xff0c;进行组装发送 //这个代码没有进行过优化&#xff0c;会产…

大衣哥给儿媳买回来烟花,是准备加入河南炮击山东大战吗

自从取得抗疫阶段性胜利后&#xff0c;国人就再也难以按捺激动的心情&#xff0c;都想通过放烟花以示庆祝。河南山东属于搭界的两个省&#xff0c;最近就因为放烟花&#xff0c;闹出来不小的笑话&#xff0c;有人甚至戏称炮击事件。 事情的起因是这样的&#xff0c;河南因为地处…

maven的build节点配置

虽然一直在使用maven&#xff0c;但是对于maven的配置还没有深入的了解过。本文以build节点为切入点&#xff0c;主要解释相关maven打包使用到的一些基础配置。 文章目录build节点常用插件spring-boot-maven-pluginmaven-jar-pluginmaven-dependency-plugin注意事项build节点 …

基于javaweb的会议管理系统源码+数据库,javaEE会议管理系统源码

guihaiyidao_git 介绍 javaEE工程 普通的javaEE工程&#xff0c;用idea打开工程即可运行 服务器用的是Tomcat 8.5.722 数据库用的Oracle xe版 数据库可视化工具使用的是PLSQL 相关软件 需要可从百度网盘中获取 链接&#xff1a;https://pan.baidu.com/s/1ZrmfsvQEA4dIP0GF_p…

CSS 布局 - 水平 垂直对齐

CSS 布局 - 水平 & 垂直对齐 那么怎样设置居中对齐呢? 我们可以用margin: auto来设置水平居中对其元素。auto可以防止 元素的宽高溢出&#xff0c;而且也可以平均分配两边的空白。 举例说明: .center {padding: 23px;border: 5px solid red;width: 41%;margin: auto; }那…

【数据结构】单向链表的原理及实现

1.什么是单链表 链表里的数据是以节点的方式表示的&#xff0c;每一个结点的组成是由&#xff1a;元素指针来组成的&#xff0c;元素就是存储数据里的存储单元&#xff0c;指针就是用来连接每一个结点的地址数据。这个以结点的序列来表示线性表被称作为单链表。 单链表是一种…

牛客寒假算法集训营1 补题

标题迷惑大赏 A、World Final? World Cup! 题目描述 众所周知&#xff0c;2022年是四年一度的世界杯年&#xff0c;那么当然要整点足球题。本题需要你模拟一次点球大战。 假设对战双方为A和B&#xff0c;则点球大战中双方会按照ABABABABAB方式来罚点球&#xff0c;即两队交…

【闪电侠学netty】第7章 数据载体ByteBuf的介绍

1. 内容概要 1.1 总结 1.1.1 内存管理 Netty 使用的是堆外内存&#xff0c;需要手动释放&#xff0c;使用引用计数的方式管理内存&#xff0c;当引用计数 0&#xff0c;回收ByteBuf 底层内存 原则&#xff1a;谁使用retain() , 谁释放release() 1.1.2 创建ByteBuf的方式 B…

ASCII码,字符,字符串三者之间的关系

程序调试中遇到问题&#xff1a;在使用sprintf 函数&#xff0c;在转换字符串时&#xff0c;如果遇到0时&#xff0c;会自动认为是结束标志&#xff0c;0以后的内容不会被添加进来。复习一下字符串&#xff1a;一. ASCII码是什么&#xff1f;ASCII 全称为 ( American Standard …

【2023更新】通过硬件触发信号实现OAK多相机之间的同步拍摄

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手…

经典文献阅读之--NeRF-SLAM(单目稠密重建)

0. 简介 最近几年随着深度学习的发展&#xff0c;现在通过深度学习去预估出景深的做法已经日渐成熟&#xff0c;所以随之而来的是本文的出现《Real-Time Dense Monocular SLAM with Neural Radiance Fields》。这篇文章是一个结合单目稠密SLAM和层次化体素神经辐射场的3D场景重…

【自学Docker 】Docker管理命令大全(下)

文章目录Docker kill命令Docker kill命令概述Docker kill命令语法Docker kill命令参数案例使用容器 ID 杀掉容器使用容器名杀掉容器Docker kill命令总结Docker rm命令Docker rm命令概述Docker rm命令语法Docker rm命令参数案例删除已停止的容器删除正在运行的容器Docker rm命令…

13.拷贝控制

文章目录拷贝控制13.1拷贝、赋值与销毁13.1.1拷贝构造函数合成拷贝构造函数拷贝初始化参数和返回值编译器可以绕过拷贝构造函数13.1.2拷贝赋值运算符重载赋值运算符合成拷贝赋值运算符13.1.3析构函数析构函数完成什么工作什么时候会调用析构函数合成析构函数13.1.4三/五法则需要…

寒假题练——day(4)

题目 1 一个数组中只有两个数字是出现一次&#xff0c;其他所有数字都出现了两次。 编写一个函数找出这两个只出现一次的数字。 #include<stdio.h> int main() {int arr[] { 1, 3, 8, 1, 3, 8, 4, 6 };int num 0;int sz sizeof(arr) / sizeof(arr[0]);int i 0;int…

【Linux】六、Linux 基础IO(二)|重定向|如何理解 Linux一切皆文件|缓冲区

目录 五、重定向 5.1 什么是重定向 5.2 系统调用 dup2 5.3 三种重定向测试 5.3.1 输出重定向(>) 5.3.2 追加重定向(>>) 5.3.3 输入重定向(<) 5.4 父子进程拷贝问题 六、如何理解 Linux一切皆文件 七、缓冲区 7.1 认识缓冲区 7.2 缓冲区的刷新策略 …

连续系统PID的Simulink仿真-2

仍以二阶线性传递函数为被控对象&#xff0c;进行模拟PID 控制。被控对象形式为,其中b为在[103,163]范围内随机变化&#xff0c;a为在[15,35]范围内随机变化&#xff0c;则被控对象的描述方式可转换为&#xff1a;S函数是Simulink一项重要的功能&#xff0c;采用S函数可实现在S…

Pandas 数据清洗

Pandas 数据清洗数据清洗是对一些没有用的数据进行处理的过程。很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况&#xff0c;如果要对使数据分析更加准确&#xff0c;就需要对这些没有用的数据进行处理。在这个教程中&#xff0c;我们将利用 Pandas包来进行数…

微软ATP带你看| 爆火的ChatGPT是什么?

&#xff08;本文阅读时间&#xff1a;7分钟&#xff09;OpenAI最新聊天机器人ChatGPT火爆全网&#xff01;能写代码、编剧本&#xff0c;马斯克都盛赞它“好得吓人”&#xff01;ChatGPT是什么GPT(Generative Pre-trained Transformer)系列是由OpenAI提出的非常强大的预训练语…

MaxCompute SQL示例解析

MaxCompute SQL示例解析 介绍MaxCompute SQL常见使用场景&#xff0c;掌握SQL的写法。 准备数据集 本文以emp表和dept表为示例数据集。您可以自行在MaxCompute项目上创建表并上传数据。 emp.csv中数据如下 7369,SMITH,CLERK,7902,1980-12-17 00:00:00,800,20 7499,ALLEN,SALES…

aws codebuild 使用和配置codebuild测试报告

参考资料 使用 Amazon CodeBuild 中的测试报告在 CodeBuild 使用AWS CLI样本中创建测试报告aws-codebuild-samples 在codebuild构建过程中获取有关在构建期间运行的测试的详细信息。 codebuild测试报告 通过在buildspec.yaml中配置报告组&#xff0c;运行构建项目时系统将运…