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

【Spring】 AOP 核心原理,与声明式事务传播机制

一、什么是 AOPAOPAspect Oriented Programming面向切面编程核心思想在不修改原有业务代码的情况下对方法进行统一增强。例如日志记录权限校验事务管理性能统计异常处理这些都属于“公共功能”不应该和业务代码耦合在一起。为什么需要 AOP传统开发public void save(){// 日志// 权限校验// 事务// 业务代码}问题代码重复耦合度高不方便维护修改公共逻辑需要改很多地方AOP 的做法把公共逻辑抽取出来在方法执行前后动态置入。二、AOP 的核心概念1.五个概念术语含义用人话解释Joinpoint (连接点)程序中可植入增强的代码点具体来说就是系统中的各个方法。PointCut (切入点)真正决定要被拦截、增强的方法集合也就是我们定义的拦截规则如某个包下的所有方法。Advice (通知/增强)切面主要做的事情是具体的业务代码比如“在方法前记日志”、“在方法后提交事务”。Aspect (切面)切入点 通知 的集合一个切面定义了在哪里PointCut做什么Advice。Proxy (代理)Spring AOP 底层通过代理实现真正执行的是代理对象不是原对象代理对象包装了原有业务对象并织入了增强逻辑。2.通知类型1. Before()前置通知方法执行前执行如权限校验参数校验2. After 后置通知方法执行后执行无论是否异常都会执行类似finally3. AfterReturning 返回通知方法正常返回后执行4. AfterThrowing 异常通知方法发生异常时执行5. Around 环绕通知最重要可以方法前增强方法后增强控制方法是否执行修改返回值统计耗时3.Around 环绕通知举例// Aspect 表明这是一个切面类 // Order(1) 有多个切面时数字越小优先级越高最先被执行 Aspect Order(1) Component // 必须交给 Spring 容器管理 public class TimeAspect { Around(⭐execution(* com.demo.controller.*.*(..))) public ⭐Object around(ProceedingJoinPoint pjp) ⭐throws Throwable { // 1. 方法执行前记录开始时间 long start System.currentTimeMillis(); // 2. 执行目标方法 ⭐Object result pjp.proceed(); // 3. 方法执行后记录结束时间 long end System.currentTimeMillis(); System.out.println(耗时 (end - start)); return result; } }⭐execution 切点表达式execution(访问修饰符 返回值 包名.类名.方法名(参数))*匹配任意字符任意返回值service 包下任意类任意方法任意参数..任意层级例如com.demo..⭐Around 返回 Object因为要兼容所有方法返回值除了Around类型外其他通知Before, After 等定义时建议设为void不写返回值即使写了Spring 也会忽略不会被作为业务返回值传给调用方⭐pjp.proceed()必须手动用throws Throwable抛出不能在这里try-catch将异常截获否则原本的异常处理逻辑如AfterThrowing或统一异常处理将失效⭐ProceedingJoinPointpjp.proceed()作用是执行目标方法除环绕通知外的其他通知类型会自动执行目标方法但是环绕通知必须手动执行♦ Around 做什么了记录耗时♦Pointcut切点复用//定义切点 Pointcut(execution(* com.demo.service.*.*(..))) public void pt(){} //使用切点 Before(pt())4.AOP 执行流程Spring 启动时扫描 Bean找到带有Aspect的切面类找到切点表达式判断哪些 Bean 需要增强为这些 Bean 创建代理对象调用方法时执行增强逻辑5.Spring AOP 底层原理代理对象是在程序运行期间动态生成的将方法调用从客户端拦截下来由代理对象执行一些额外的逻辑增强然后再选择是否调用目标对象Target的原始方法静态代理vs 动态代理静态代理手动为每个目标类编写一个代理类编译为.class文件。在代码运行前就已经确定。缺点随着业务类增加代理类数量暴增难以维护。动态代理Spring AOP 采用在程序运行期间由框架在内存中动态生成代理对象。不需要手动编写.class文件。动态代理动态代理先生成“类字节码”再根据这个类去创建“Bean 实例”1JDK 动态代理目标类必须实现类接口代理类动态创建一个实现相同接口的类2CGLIB 动态代理通过继承目标类生成子类代理不需要接口Spring 默认优先使用 JDK没有接口时使用 CGLIBSpring 动态代理的决策逻辑常问如果目标对象实现了接口默认使用JDK 动态代理。如果目标对象未实现接口则必须使用CGLIB 动态代理。【注】Spring Boot 2.x 后默认配置可能偏向全员使用 CGLIB 以避免因为是否实现接口导致的行为不一致。派系实现机制优缺点/适用场景JDK 动态代理基于接口实现。代理类与目标类实现相同的接口。通过InvocationHandler和Proxy类实现。优点速度快。缺点只能代理实现了接口的类。若无接口无法使用。CGLIB 动态代理基于继承实现。生成的代理类是目标类的子类。使用底层字节码技术生成。优点可以代理没有接口的类。性能在某些场景下优于 JDK。缺点不能代理final方法。final类不能被继承三、Spring 事务事务是保证数据完整性和一致性的核心手段。在 Spring 中我们通过简单的一个Transactional注解即可实现这一复杂功能其底层同样是基于AOP 代理机制1. 事务的核心概念Transaction定义将一组逻辑上相关的操作包装成一个原子单位这些操作要么全部成功要么全部失败。底层支撑Spring 本身并不管理事务而是提供了一套一致的接口具体实现依赖底层的数据库如 MySQL 的 InnoDB 引擎支持事务MyISAM 不支持。2. 声明式事务 vs 编程式事务编程式事务在业务代码中手动写commit()、rollback()逻辑。缺点侵入性强难以维护。声明式事务AOP 代理形式在方法或类上加上Transactional注解。底层原理Spring 产生目标类的代理对象。当调用方法时代理对象先开启事务然后执行业务逻辑如果没有发生异常则代理提交事务如果发生特定异常则代理回滚事务。3. Transactional 的核心配置要点作用域可以作用在方法上也可以作用在类上类下所有方法都生效。底层 AOP 切点实现思路切点所有加了Transactional的方法。通知逻辑Advice代理开启事务TransactionStatus状态 - 执行原业务 - 成功则代理提交 / 失败则代理回滚。4. 事务回滚规则设置默认回滚异常Spring 只对RuntimeException运行时异常和Error进行回滚。注意IOException检查异常、FileNotFoundException等默认是不回滚的必须手动配置。解决方案Transactional(rollbackFor Exception.class)推荐全员配置拦截所有类型的异常。或者手动try-catch异常并在代码中调用底层 API 手动回滚但这就变成了编程式事务。5. 事务传播属性Propagation - 面试必问当一个事务方法调用另一个事务方法时事务应该如何处理propagation Propagation.REQUIRED(默认值)外层方法有事务就加入如果没有外层方法自己新建一个。propagation Propagation.REQUIRES_NEW无论外层有没有事务自己都必须新建一个事务并且把外层事务挂起如果是外层事务调入两个事务互不影响外层异常回滚不影响子事务。【注】这种策略在处理写独立审计日志、发放奖品等逻辑时非常常用。四、Spring 事务传播机制为了方便理解我们统一设定一个代码调用背景方法 A开启了事务或没有。方法 A 内部调用了方法 B方法 B 配置了不同的传播机制传播行为 (Propagation)外层A有事务时外层A无事务时说明REQUIRED(默认)加入A事务新建事务融合在一起同生共死REQUIRES_NEW挂起A新建事务新建事务彼此独立互不干扰NESTED嵌套子事务(Savepoint)新建事务A崩全崩B崩A可不崩SUPPORTS加入A事务非事务运行随遇而安NOT_SUPPORTED挂起A非事务运行非事务运行拒绝事务强制裸奔MANDATORY加入A事务抛出异常必须有靠山没靠山就罢工NEVER抛出异常非事务运行见事务就见光死同类方法调用失效问题如果方法 A 和方法 B 在同一个 Service 类里方法 AREQUIRED调用方法 BREQUIRES_NEWB 的新事务会生效吗答案不会生效因为 Spring 事务基于 AOP 动态代理。类内部的直接方法调用this.B()指向的是真实目标对象而不是外面的代理对象导致 B 的Transactional注解直接被忽略B 会直接沿用 A 的事务等同于 REQUIRED。根本原因this.B()是一次普通的 JVM 内部方法调用根本没有走 Spring 代理对象的业务分发链路。既然没经过代理加在B()上的所有 AOP 注解事务、日志、权限自然全部失效。流程:外部调用如 Controller 调用userService.A()---------调用首先走到UserService代理对象---------代理对象触发开启事务---------代理对象内部调用target.A()---------A()方法内正在执行的是目标对象的代码---------A调用this.B---------调用的是真实目标对象Service public class UserService { Transactional public void A() { // 外部调用进来事务成功开启 // 此时 code 在 Target 对象内部运行 this.B(); // 相当于 target.B(); } Transactional(propagation Propagation.REQUIRES_NEW) public void B() { // 因为是 target 直接调用的没有经过外面的 Proxy // 代理对象身上的 AOP 增强新开事务直接被绕过了 } }解决办法使用AopContext.currentProxy()获取当前代理对象去调用 B或者将 B 拆分到不同的 Service 类中。①核心大三策略最常用这是笔记中重点标记、面试出镜率高达 90% 的三种机制。1. REQUIRED必须有事务—— 默认策略人话解释有同享无自建。业务逻辑若 A有事务B 就会加入A 的事务变成同一个事务。若 A没有事务B 就会自己新建一个事务。致命痛点由于 A 和 B 在同一个事务中其中任何一处报错导致回滚全盘回滚即便 B 报错被 A 用try-catch捕获了也会因为全局事务被标记为rollback-only而引发异常回滚。2. REQUIRES_NEW必须新事务人话解释不管你有没有我都要住单间。业务逻辑不管 A 有没有事务B 都会开启一个全新的事务。若 A有事务A 会先挂起Suspend等待 B 的事务运行完A 再继续运行。影响结果A 和 B 是两个独立的事务。B 报错回滚不会影响 A 的正常提交前提是 A 捕获了 B 的异常同理A 后面报错回滚也绝对不会影响已经提交的 B 事务。典型场景记录审计日志、发放独立优惠券。无论核心下单业务成功与否日志必须入库。3. NESTED嵌套事务业务逻辑若 A有事务B 会在 A 的事务内部设立一个保存点Savepoint。关键特质局部回滚如果 B 报错回滚B 只会回滚到 Savepoint不影响 A 事务的执行A 捕获异常后可以继续提交。全局连坐如果 A 报错回滚由于 B 是嵌套在 A 里面的AB 会全部回滚。② 挂载与不支持策略3个不常用这三个策略通常用于优化特定场景下的性能如纯查询逻辑。4. SUPPORTS支持事务业务逻辑A有事务B 就加入A 的事务。A没有事务B 就以非事务普通方式运行。典型场景只读查询方法。5. NOT_SUPPORTED不支持事务业务逻辑始终以非事务方式运行。即使 A有事务B 也会把 A 的事务挂起等自己用非事务方式裸奔完再恢复 A 的事务。6. MANDATORY强制要求有事务业务逻辑极度傲娇。A必须有事务B 才会加入。若 A没有事务B 直接抛出异常IllegalTransactionStateException。③ 绝对禁区7. NEVER禁用事务业务逻辑始终以非事务方式运行。如果 A有事务B 逮到直接抛出异常。

相关文章:

【Spring】 AOP 核心原理,与声明式事务传播机制

一、什么是 AOPAOP(Aspect Oriented Programming,面向切面编程)核心思想在不修改原有业务代码的情况下,对方法进行统一增强。例如:日志记录;权限校验;事务管理;性能统计;…...

SDR++软件无线电:3个关键步骤让你轻松探索无线电频谱世界

SDR软件无线电:3个关键步骤让你轻松探索无线电频谱世界 【免费下载链接】SDRPlusPlus Cross-Platform SDR Software 项目地址: https://gitcode.com/GitHub_Trending/sd/SDRPlusPlus 你是否曾经好奇过无线电波中隐藏着怎样的秘密?从FM广播到航空通…...

第十章:什么是Agentic AI?——让AI从“回答问题“到“替你办事“

难度级别:★★★★☆ | 预计阅读时间:15分钟 你将学到:Agentic AI的核心能力、技术架构、主流框架对比、PM选型决策框架、以及如何设计一个AI Agent系统 引言:从"工具"到"代理"的跨越 一个真实的痛点 某科技公司的研究员小王,每天需要花3小时完成以…...

Potree加载点云实战:从CloudCompare检查到浏览器3D展示的全链路避坑

Potree点云加载全流程实战:从数据验收到3D可视化的深度指南 点云数据正逐渐成为三维地理信息系统、建筑信息模型和数字孪生领域的核心载体。作为开源点云可视化库的佼佼者,Potree以其高效的Web端渲染能力赢得了众多开发者的青睐。然而在实际项目集成过程…...

如何确认Excel的识别范围

1.打开想要看的excel sheet2.ALTF11 打开工具VBA3.CTRLG呼出及时窗口4.输入?ActiveSheet.UsedRange.Address...

告别繁琐操作:用VSCode插件‘Open in Browser’和‘CSS Peek’打造流畅的实时预览调试工作流

极速开发实战:VSCode插件组合拳实现HTML/CSS无缝调试 每次修改完CSS样式都要手动切换到浏览器刷新页面?在庞大的代码库中寻找某个CSS定义像大海捞针?这些问题困扰着无数前端开发者。今天我们将解锁VSCode中两个看似简单却威力巨大的插件——O…...

别再手动一个个改了!ArcGIS属性表字段批量删除与数据裁剪的‘偷懒’技巧

ArcGIS高效工作流:属性表与数据批处理的进阶技巧 在GIS工程师的日常工作中,最令人头疼的莫过于那些看似简单却需要重复上百次的操作——删除几十个无用字段、裁剪数百个栅格图层、批量修改投影坐标系。这些机械性劳动不仅消耗时间,更消磨创造…...

AI行业4大神仙岗位,0基础也能拿下?薪资直逼200万!

文科生,能进AI行业吗? 毕业做了两年行政,现在想转行,是不是来不及了? 看到AI岗位都要写代码,我连Python都没碰过,是不是没戏了? … 想一想都是问题,做一做一定会有答案&a…...

泛微发布300+可落地AI应用 让组织业务数智升级

5月20日,泛微300AI应用场景体验大会在上海举办。大会以“组织的AI范式数字员工与业务流程AI新生”为主题, 展示泛微全场景AI应用。泛微搭载五大智能引擎,提供300可快速落地的AI应用场景,覆盖市场、销售、项目、合同、采购、财务、…...

别再只用TabBar了!用Qt QML的Repeater和ListView打造更灵活的侧边栏导航(附完整源码)

超越TabBar:用QML的Repeater与ListView构建动态导航系统 当标准导航控件无法满足现代应用界面需求时,Qt Quick的模型-视图架构提供了更强大的解决方案。本文将深入探讨如何利用Repeater和ListView构建高度可定制的侧边栏导航系统,通过对比分析…...

擎天租与京东集团达成战略合作,机器人服务加速进入全域场景

5月21日,擎天租宣布与京东集团达成全面战略合作,双方将围绕产品解决方案共建、渠道供应链赋能及规模化采购等方面展开深度合作。此次战略联手,不仅是两家标杆企业在各自优势领域的双向赋能,也将推动RaaS(Robot as a Se…...

2026年双语论文降AI攻略:中英文双语毕业论文AIGC超标免费4.8元达标完整指南

2026年双语论文降AI攻略:中英文双语毕业论文AIGC超标免费4.8元达标完整指南 双语论文降AI这件事,踩过坑的人都知道:工具选错、操作方式错,钱白花还耽误时间。 直接给结论:嘎嘎降AI(www.aigcleaner.com&am…...

王力宏重仓比亚迪,行业震惊

王力宏最近以腾势汽车全球代言人的身份亮相发布会,现场直言:“后悔10年前没投资比亚迪,这次我要把握机会。” 当被问及是否用代言费买了比亚迪股票,他大方承认“这是真的”。他还补充道:“10年前我做过一档节目&#x…...

树莓派5/4B新手开箱:用官方Raspberry Pi Imager工具10分钟完成系统部署

树莓派5/4B极速部署指南:官方Imager工具的全新工作流解析 第一次拿到树莓派5或4B时,很多用户会陷入传统部署方法的复杂流程中——下载镜像、格式化存储卡、烧录系统、手动配置网络……这些步骤不仅耗时,还容易因操作失误导致启动失败。而树莓…...

Themes 与 Styles

Themes 与 Styles 主题目录:Source/Themes项目说明H.Theme主题核心。H.Themes.Colors.Accent强调色。H.Themes.Colors.Blue蓝色。H.Themes.Colors.Copper铜色/复古。H.Themes.Colors.Gray灰色。H.Themes.Colors.Industrial工业风。H.Themes.Colors.Mineral矿物色。H…...

为内容生成平台构建支持多模型备选的 AI 中台

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为内容生成平台构建支持多模型备选的 AI 中台 在内容创作领域,无论是自媒体运营还是营销团队,对文本生成的…...

SX1255和AD9361的LO泄露实测对比:为什么你的无线模块EVM总是不达标?

SX1255与AD9361本振泄露实战分析:破解EVM不达标的三大关键策略 在调试LoRa模块或小型基站射频前端时,工程师们最常遇到的"幽灵问题"莫过于EVM指标莫名劣化。上周深夜,当我的频谱仪上再次出现那个熟悉的载波泄露尖峰时,我…...

【Qt学习】Windows上环境配置与项目初识

文章目录环境配置下载与安装环境变量设置查看示例程序Qt Creator界面说明快捷键项目帮助构建模式编码中文问题创建第一个Qt项目创建项目项目文件程序入口本文参照视频学习记录: https://www.bilibili.com/list/watchlater?oid970696801&bvidBV1Jp4y167R9视频中…...

告别Excel!用Python复现地理探测器(附完整代码与示例数据)

告别Excel!用Python复现地理探测器(附完整代码与示例数据) 地理探测器作为分析空间分异性的重要工具,长期以来依赖Excel插件实现计算。但对于需要批量处理、自定义分析流程的研究者而言,这种封闭式操作存在明显局限。…...

微信小程序互助交流

微信小程序互助群 你开发了一个微信小程序, 准备接广告, 卡在了 500 个 UV 这里, 想找大佬帮忙,结果大佬说要收一张费—— 于是我建了一个微信群, 大家互助,免费入群,入群条件: 每人…...

【ElevenLabs老挝文语音实战指南】:2024年唯一经实测验证的8步本地化语音合成落地方案

更多请点击: https://kaifayun.com 第一章:ElevenLabs老挝文语音合成的技术背景与本地化价值 ElevenLabs 作为全球领先的AI语音生成平台,长期聚焦于高保真、情感化多语言语音合成技术。尽管其支持语言列表持续扩展,老挝文&#x…...

Vibe Coding 实战:我用一条 Prompt 指挥 AI “盲盒式”生成 3D 积木物理世界

🚀 Vibe Coding 实战:我用一条 Prompt 指挥 AI “盲盒式”生成 3D 积木物理世界)一、 引言:欢迎来到 Vibe Coding 时代1.1 什么是 Vibe Coding?从“一行行敲代码”到“用直觉与语义编程”的范式转变1.2 为什么选择 3D …...

别再手动复制文件了!Mathtype 7.4 一键配置脚本,搞定Office和WPS(附常见错误修复)

数学公式编辑神器Mathtype 7.4全自动部署方案:告别手动配置的繁琐时代 在科研论文、技术文档撰写过程中,数学公式的编辑效率直接影响工作进度。Mathtype作为专业数学公式编辑工具,其强大功能常被手动配置的复杂步骤所掩盖。传统方法需要用户反…...

ElevenLabs台湾话语音上线后用户留存率骤降47%?揭秘方言语料清洗盲区与3步合规性校验法

更多请点击: https://intelliparadigm.com 第一章:ElevenLabs台湾话语音上线后用户留存率骤降47%?揭秘方言语料清洗盲区与3步合规性校验法 ElevenLabs于2024年Q2正式上线台湾话(闽南语)语音合成服务,初期D…...

【限时解密】ElevenLabs未公开的瑞典文语料权重配置表:仅限前200名开发者获取的/sv-SE/声道微调参数

更多请点击: https://codechina.net 第一章:瑞典文语音合成的技术背景与ElevenLabs架构定位 瑞典语作为北日耳曼语支的重要语言,拥有丰富的元音系统(9个长元音、9个短元音)、独特的声调重音(accent 1 和 a…...

2026年福建莆田大平层全屋高端定制选型指南

一、引言福建莆田近年来经济发展迅速,居民生活水平不断提高,大平层住宅逐渐成为高端改善型住房的热门选择。在全屋高端定制方面,消费者面临着众多品牌的选择。本指南旨在为莆田的大平层业主提供一份合规、靠谱且适配自身需求的高端定制品牌选…...

Midjourney盐印相风格实战手册(附12组可复用Prompt模板+SDXL交叉验证数据)

更多请点击: https://kaifayun.com 第一章:Midjourney盐印相风格的视觉溯源与美学内核 盐印相(Salted Paper Print)是19世纪早期摄影术诞生之初的核心工艺,由亨利福克斯塔尔博特于1839年系统完善。其本质是将纸基浸入…...

HS2汉化补丁终极解决方案:15分钟快速上手完整指南

HS2汉化补丁终极解决方案:15分钟快速上手完整指南 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 还在为Honey Select 2的日语界面而烦恼吗&#xf…...

D2001UK,1GHz频段下2.5W高功率输出的单端式硅DMOS RF FET射频晶体管

简介今天我要向大家介绍的是 Semelab 的硅DMOS RF FET晶体管——D2001UK。这是一款专为VHF/UHF通信频段(50 MHz至1 GHz)设计的单端式射频功率场效应管,在28V工作电压、1GHz频率下可提供2.5W的输出功率。作为一款高性能射频器件,它…...

【紧急预警】ElevenLabs 2024 Q3瑞典文语音许可证变更:3类商业场景已触发合规风险,附欧盟GDPR语音数据处理自查清单

更多请点击: https://codechina.net 第一章:ElevenLabs瑞典文语音许可证变更的合规背景与影响速览 2024年第三季度,ElevenLabs正式更新其语音合成服务的区域许可政策,将瑞典语(sv-SE)语音模型纳入欧盟《人…...