当前位置: 首页 > news >正文

15、Spring系统-AOP

ProxyFactory选择cglib或jdk动态代理原理

ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术:

代理对象创建过程

JdkDynamicAopProxy

  1. 在构造JdkDynamicAopProxy对象时,会先拿到被代理对象自己所实现的接口,并且额外的增加SpringProxy、Advised、DecoratingProxy三个接口,组合成一个Class[],并赋值给proxiedInterfaces属性
  2. 并且检查这些接口中是否定义了equals()、hashcode()方法
  3. 执行Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this),得到代理对象,JdkDynamicAopProxy作为InvocationHandler,代理对象在执行某个方法时,会进入到JdkDynamicAopProxy的**invoke()**方法中

ObjenesisCglibAopProxy

  1. 创建Enhancer对象
  2. 设置Enhancer的superClass为通过ProxyFactory.setTarget()所设置的对象的类
  3. 设置Enhancer的interfaces为通过ProxyFactory.addInterface()所添加的接口,以及SpringProxy、Advised、DecoratingProxy接口
  4. 设置Enhancer的Callbacks为DynamicAdvisedInterceptor
  5. 最后创建一个代理对象,代理对象在执行某个方法时,会进入到DynamicAdvisedInterceptor的intercept()方法中

代理对象执行过程

  1. 在使用ProxyFactory创建代理对象之前,需要往ProxyFactory先添加Advisor
  2. 代理对象在执行某个方法时,会把ProxyFactory中的Advisor拿出来和当前正在执行的方法进行匹配筛选
  3. 把和方法所匹配的Advisor适配成MethodInterceptor
  4. 把和当前方法匹配的MethodInterceptor链,以及被代理对象、代理对象、代理类、当前Method对象、方法参数封装为MethodInvocation对象
  5. 调用MethodInvocation的proceed()方法,开始执行各个MethodInterceptor以及被代理对象的对应方法
  6. 按顺序调用每个MethodInterceptor的invoke()方法,并且会把MethodInvocation对象传入invoke()方法
  7. 直到执行完最后一个MethodInterceptor了,就会调用invokeJoinpoint()方法,从而执行被代理对象的当前方法

各注解对应的MethodInterceptor

  • @Before对应的是AspectJMethodBeforeAdvice,在进行动态代理时会把AspectJMethodBeforeAdvice转成MethodBeforeAdviceInterceptor先执行advice对应的方法再执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
  • @After对应的是AspectJAfterAdvice,直接实现了MethodInterceptor先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法再执行advice对应的方法
  • @Around对应的是AspectJAroundAdvice,直接实现了MethodInterceptor直接执行advice对应的方法,由@Around自己决定要不要继续往后面调用
  • @AfterThrowing对应的是AspectJAfterThrowingAdvice,直接实现了MethodInterceptor先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法如果上面抛了Throwable,那么则会执行advice对应的方法
  • @AfterReturning对应的是AspectJAfterReturningAdvice,在进行动态代理时会把AspectJAfterReturningAdvice转成AfterReturningAdviceInterceptor先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法执行上面的方法后得到最终的方法的返回值再执行Advice对应的方法

AbstractAdvisorAutoProxyCreator

这个注解主要就是往Spring容器中添加了一个AnnotationAwareAspectJAutoProxyCreator类型的Bean。

AspectJAwareAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator,重写了findCandidateAdvisors()方法,AbstractAdvisorAutoProxyCreator只能找到所有Advisor类型的Bean对象,但是AspectJAwareAdvisorAutoProxyCreator除开可以找到所有Advisor类型的Bean对象,还能把@Aspect注解所标注的Bean中的@Before等注解及方法进行解析,并生成对应的Advisor对象。

所以,我们可以理解@EnableAspectJAutoProxy,其实就是像Spring容器中添加了一个AbstractAdvisorAutoProxyCreator类型的Bean,从而开启了AOP,并且还会解析@Before等注解生成Advisor。

Spring中AOP原理流程图

Spring中AOP底层原理| ProcessOn免费在线作图,在线流程图,在线思维导图

 

相关文章:

15、Spring系统-AOP

ProxyFactory选择cglib或jdk动态代理原理 ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术: 代理对象创建过程 JdkDynamicAopProxy 在构造JdkDynamicAopProxy对象时,会先拿到被代理对象自己所实现的接口,并且…...

服务器感染了. rmallox勒索病毒,如何确保数据文件完整恢复?

导言: 近年来,随着信息技术的飞速发展,网络安全问题日益凸显。其中,勒索病毒作为一种严重的网络威胁,对个人和企业数据造成了巨大的威胁。本文将重点介绍.rmallox勒索病毒的特点、传播途径以及应对策略,旨…...

[每日一练]按日期分组销售产品的最优解法

该题目来自于力扣的pandas题库,链接如下: 1484. 按日期分组销售产品 - 力扣(LeetCode) 题目要求: 表 Activities: ---------------------- | 列名 | 类型 | ---------------------- | sell_…...

免费wordpress中文主题

免费大图wordpress主题 首页是一张大图的免费wordpress主题模板。简洁实用,易上手。 https://www.jianzhanpress.com/?p5857 免费WP模板下载 顶部左侧导航条的免费WP模板,后台简洁,新手也可以下载使用。 https://www.jianzhanpress.com/…...

单链表经典算法题理解

目录 1. 前言: 2. 移除链表元素 3. 反转链表 4. 合并两个有序链表 5. 链表的中间节点 6. 环形链表的约瑟夫问题 7. 分割链表 1. 前言: 当我们学习了单链表之后,我能可以尝试的刷一下题了,以下分享一下几道题的解法 2. 移…...

STM32的时钟介绍

目录 前言1. 简介1.1 时钟是用来做什么的1.2 时钟产生的方式 2. 时钟树的组成2.1 时钟源2.1.1 内部时钟2.1.2 外部时钟 2.2 PLL锁相环2.3 SYSCLK2.4 AHB和HCLK2.5 APB和PCLK2.6 总结 3. STM32时钟的如何进行工作4.我的疑问4.1 使用MSI和HSI有什么区别吗?4.2 MSI的频…...

FindBI学习总结

大数据分析BI工具:用户只需简单拖拽便能制作出丰富多样的数据可视化信息 关注点: 快速入门、数据加工、构建图表和分析数据、数据分析进阶 1、界面介绍 目录–仪表板–数据准备 仪表板目录–预览区域 快速上手: 1、数据准备2、制作仪表板3、分…...

k8s——Pod详解

一、Pod基础概念 1.1 Pod定义 Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的,例如,用于管理Pod运行…...

Visual Studio 的调试

目录 引言 一、调试的基本功能 设置断点 启动调试 检查变量 逐步执行代码 调用堆栈 使用即时窗口 二、调试技巧 条件断点 日志断点 数据断点 异常调试 三、调试高级功能 远程调试 多线程调试 内存调试 性能调试 诊断工具 四、调试策略与最佳实践 系统化的…...

mysql语句大全及用法

MySQL是一种广泛使用的开源关系型数据库管理系统,它支持标准的SQL(Structured Query Language)语言,用于数据库的查询和操作。以下是一些基本的MySQL语句及其用法的概述: 连接MySQL数据库 mysql -h主机地址 -P端口号…...

如何找出真正的交易信号?Anzo Capital昂首资本总结7个

匕首是一种新兴的价格走势形态,虽然不常见,但具有较高的统计可靠性。它通常预示着趋势的持续发展。该模式涉及到同时参考两个不同的时间周期进行交易,一个是短期,另一个是长期,比如一周时间框架与一天时间框架、一天时…...

JavaScript-内存分配

内存空间 内存分为栈和堆 栈:由操作系统自动释放存放的变量值和函数值等。简单数据类型存放在栈中 栈会由低到高先入后出 堆:存储引用类型 (对象) 对象会先将数据存放在堆里面,堆的地址放在栈里面...

理论知识.质数打表

啊,哈喽,小伙伴们大家好。我是#张亿,今天呐,学的是理论知识.质数打表 为什么需要质数打表 我们已经学习了如何判断一个数是不是质数了,但是还不够。假设要判断很多很多个数是不是质数的时候,之前的学习的…...

FFMPEG+ANativeWinodow渲染播放视频

前言 学习音视频开发,入门基本都得学FFMPEG,按照目前互联网上流传的学习路线,FFMPEGANativeWinodow渲染播放视频属于是第一关卡的Boss,简单但是关键。这几天写了个简单的demo,可以比较稳定进行渲染播放,便…...

使用AXI MIG/Proc Sys Reset

使用AXI MIG/Proc Sys Reset 重要!仅当您的设计中包含AXI MIG时,才执行以下步骤。 AXI-MIG的连接接口 1.选择在/mig_7series_0/S_AXI上运行连接自动化。 2.选择/micblaze_0(缓存)或/micblaze _0(Periph)选项…...

Android基础-Kotlin语言的作用及优缺点

一、Kotlin语言的作用 Kotlin是一种由JetBrains公司开发的现代化静态类型编程语言,自其诞生以来,便在多个领域展现出了强大的应用潜力。其主要作用可以概括为以下几点: Android应用开发:Kotlin作为Android开发的官方推荐语言&am…...

手机投屏技巧:手机怎么投屏到电脑显示屏上?精选6招解决!

手机怎么投屏到电脑显示屏上?出于一些不同的原因,大多数人都希望能将手机投屏到电脑上。其中一个常见的原因是,大家经常会希望在笔记本电脑上共享图片,而无需上传或者登录微信进行文件传输。以及希望不依靠投影仪,就能…...

内存函数<C语言>

前言 前面两篇文章介绍了字符串函数,不过它们都只能用来处理字符串,C语言中也内置了一些内存函数来对不同类型的数据进行处理,本文将介绍:memcpy()使用以及模拟实现,memmove()使用以及模拟实现,memset()使用…...

华为校招机试 - LRU模拟(20240515)

题目描述 LRU(Least Recently Used)缓存算法是一种常用于管理缓存的策略,其目标是保留最近使用过的数据,而淘汰最久未被使用的数据。 实现简单的LRU缓存算法,支持查询、插入、删除操作。 最久未被使用定义:查询、插入和删除操作均为一次访问操作,每个元素均有一个最后…...

AI预测福彩3D采取888=3策略+和值012路一缩定乾坤测试5月29日预测第5弹

今天继续基于8883的大底,使用尽可能少的条件进行缩号,同时,同样准备两套方案,一套是我自己的条件进行缩号,另外一套是8883的大底结合2码不定位奖号预测二次缩水来杀号。好了,直接上结果吧~ 首先&…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...