Spring Boot AOP(三) 通知执行链源码解析

Spring Boot AOP(三) 通知执行链源码解析
博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。 ② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。 ③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送ZEEKLOG评论防封脚本,送真活跃粉丝,助你提升文章热度。 群公告里还有全网大赛约稿汇总/博客提效工具集/ZEEKLOG自动化运营脚本 有兴趣的加文末联系方式,备注自己的ZEEKLOG昵称,拉你进群,互相学习共同进步。 

文章目录


Spring Boot AOP(三) 通知执行链源码解析

1. 执行链概述

在 Spring AOP 中,一个方法可能对应 多个切面(Aspect)多个通知(Advice)。Spring 使用 Advisor 链 + MethodInterceptor 链 来统一管理这些通知,使方法执行时按顺序执行各类通知。

核心概念

概念说明
Advisor切面 + 切入点 + 通知的组合对象
Advice切面中具体执行的操作,例如 @Before、@After、@Around
MethodInterceptorAOP 的统一调用接口,所有 Advice 最终都转换为 MethodInterceptor
ReflectiveMethodInvocation方法调用封装类,负责顺序调用 Advisor 链
Spring AOP 的通知最终都会被封装为 MethodInterceptor,执行链由 ReflectiveMethodInvocation 管理。

2. Advisor 链与通知统一处理

在 Spring 中,多个切面可能作用于同一个方法。Spring 会将所有切面对应的通知 排序后加入 Advisor 链

  1. 收集匹配的切面
  2. 将切面中的 Advice 转换为 MethodInterceptor
  3. 按 @Order 或实现 Ordered 接口排序
  4. 构建 ReflectiveMethodInvocation 执行链

Mermaid 流程图:Advisor 链构建

扫描 Bean 切面

匹配切入点

收集匹配的通知

Advice 转换为 MethodInterceptor

按顺序构建 ReflectiveMethodInvocation 链


3. MethodInterceptor 执行流程

3.1 ReflectiveMethodInvocation 核心源码

核心方法:proceed()

publicObjectproceed()throwsThrowable{if(this.currentInterceptorIndex ==this.interceptorsAndDynamicMethodMatchers.size()-1){returnthis.method.invoke(this.target,this.arguments);}Object interceptorOrAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if(interceptorOrAdvice instanceofMethodInterceptor){return((MethodInterceptor) interceptorOrAdvice).invoke(this);}else{returnproceed();}}

3.2 执行逻辑说明

  1. currentInterceptorIndex 控制当前执行的通知
  2. 如果到达链尾,则调用目标方法
  3. 否则,将当前通知强转为 MethodInterceptor 并调用
  4. 每个环绕通知内部可以调用 proceed() 执行下一环节

Mermaid 流程图:MethodInterceptor 调用链

渲染错误: Mermaid 渲染失败: Parse error on line 3: ...>proceed] B --> C[@Before 前置通知] ----------------------^ Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'LINK_ID'


4. 不同通知类型执行链示意

通知类型转换为 MethodInterceptor执行顺序
前置通知 @BeforeMethodBeforeAdviceInterceptor最先执行
环绕通知 @AroundAroundAdviceInterceptor可环绕目标方法
返回通知 @AfterReturningAfterReturningAdviceInterceptor目标方法成功返回后执行
异常通知 @AfterThrowingAfterThrowingAdviceInterceptor目标方法异常时执行
后置通知 @AfterAfterAdviceInterceptor最后执行,无论成功/异常

5. 环绕通知执行链深入解析

环绕通知最灵活,可以完全控制方法执行:

@Around("execution(* com.example.service..*.*(..))")publicObjectaroundAdvice(ProceedingJoinPoint pjp)throwsThrowable{System.out.println("环绕通知前逻辑");Object result = pjp.proceed();System.out.println("环绕通知后逻辑");return result;}

Mermaid 流程图:环绕通知链执行

方法调用

环绕通知1前逻辑

环绕通知2前逻辑

目标方法执行

环绕通知2后逻辑

环绕通知1后逻辑

返回调用方


6. 多 Advisor 链组合示例

@Aspect@Component@Order(1)publicclassLoggingAspect{@Before("execution(* com.example.service..*.*(..))")publicvoidbefore(JoinPoint jp){System.out.println("日志前置: "+ jp.getSignature());}}@Aspect@Component@Order(2)publicclassTransactionAspect{@Around("execution(* com.example.service..*.*(..))")publicObjectaround(ProceedingJoinPoint pjp)throwsThrowable{System.out.println("事务开始");Object result = pjp.proceed();System.out.println("事务提交");return result;}}@Aspect@Component@Order(3)publicclassMetricsAspect{@AfterReturning(pointcut ="execution(* com.example.service..*.*(..))", returning ="result")publicvoidafterReturning(JoinPoint jp,Object result){System.out.println("性能监控: "+ jp.getSignature()+", 返回: "+ result);}}

多切面执行顺序示意

方法调用

LoggingAspect @Before

TransactionAspect @Around 前

目标方法执行

TransactionAspect @Around 后

MetricsAspect @AfterReturning

返回调用方


7. ReflectiveMethodInvocation 执行链源码示意

proceed 方法调用

获取当前索引的 MethodInterceptor

索引是否到达链尾?

执行目标方法 method.invoke

执行当前拦截器

interceptor.invoke this

拦截器内部调用 proceed

返回结果

逐层返回到调用方


8. 本文总结

  • Spring AOP 统一将所有通知封装为 MethodInterceptor
  • ReflectiveMethodInvocation 负责 链式执行所有通知
  • 环绕通知可以完全控制目标方法执行,其他通知按 Advisor 链顺序执行
  • 多切面组合执行顺序由 @OrderOrdered 接口控制
  • Mermaid 图直观展示了 Advisor 链、方法调用链和环绕通知执行顺序

这一篇是 源码级、流程图丰富、示例全面 的第三篇,紧接第二篇的代理机制,完整衔接整个系列。

下一步可以写 第四篇:Spring Boot /error 与 BasicErrorController 源码解析 或你希望继续写 异常与 AOP 结合的执行顺序 这一主题,你希望我直接写哪一个?

结束语

👨‍💻 关于我

持续学习 | 追求真我

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

感谢订阅专栏 三连文章

image-20251011155556997

掘金点击访问QiunerZEEKLOG点击访问QiunerGitHub点击访问QiunerGitee点击访问Qiuner

专栏简介
📊 一图读懂系列图文并茂,轻松理解复杂概念
📝 一文读懂系列深入浅出,全面解析技术要点
🌟持续更新保持学习,不断进步
🎯 人生经验经验分享,共同成长
你好,我是Qiuner. 为帮助别人少走弯路而写博客

如果本篇文章帮到了你 不妨点个吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

代码都在Github或Gitee上,如有需要可以去上面自行下载。记得给我点星星哦😍

如果你遇到了问题,自己没法解决,可以去我掘金评论区问。ZEEKLOG评论区和私信消息看不完 掘金消息少一点.
上一篇推荐链接
Java程序员快又扎实的学习路线点击该处自动跳转查看哦
一文读懂 AI点击该处自动跳转查看哦
一文读懂 服务器点击该处自动跳转查看哦
2024年创作回顾点击该处自动跳转查看哦
一文读懂 ESLint配置点击该处自动跳转查看哦
老鸟如何追求快捷操作电脑点击该处自动跳转查看哦
未来会写什么文章?预告链接
一文读懂 XX?点击该处自动跳转查看哦
2025年终总结点击该处自动跳转查看哦
一图读懂 XX?点击该处自动跳转查看哦

Read more

Java WebFlux集成DeepSeek大模型:流式接入完整实现(含代码+优化+避坑)

Java WebFlux集成DeepSeek大模型:流式接入完整实现(含代码+优化+避坑)

Java WebFlux集成DeepSeek大模型:流式接入完整实现(含代码+优化+避坑) 前言:随着大模型技术的普及,Java后端接入DeepSeek等大模型时,传统同步阻塞式调用已无法满足高并发、低延迟的业务需求。本文基于Spring WebFlux响应式框架,详细讲解大模型流式接入的技术方案、完整实现代码、性能优化技巧及常见问题解决方案,全程干货,可直接落地到生产环境。 关键词:Java WebFlux;DeepSeek;流式接入;SSE;响应式编程;大模型集成 一、技术背景与需求分析 在Java后端开发中,接入DeepSeek等大模型进行AI推理时,传统同步HTTP调用模式存在诸多痛点,而流式处理结合WebFlux的响应式特性,成为解决该问题的最优路径。 1.1 传统AI模型接入的局限性 传统Java应用接入AI推理模型,普遍采用同步阻塞式HTTP请求(如OkHttp、RestTemplate同步调用),这种模式在对接DeepSeek等大模型时,瓶颈尤为突出,具体表现为三点: * 高延迟导致线程阻塞:DeepSeek等大模型单次推理耗时通常在1-5秒

By Ne0inhk

解放双手,让 AI 帮咱审查代码——GitLab 智能审查实战指南

unsetunset一、题记unsetunset 你是不是有如下这些困扰? 困惑1:代码审查效率低下。 团队成员提交的 MR(Merge Request)堆积如山,人工审查耗时耗力,经常因为时间紧迫而草草通过? 困惑2:代码质量参差不齐。 新人代码风格不统一,老手也难免疏忽,潜在的安全风险和性能问题常常在上线后才暴露?  曾几何时,13年前作为新入职员工,每隔几个月都要参加公司的代码规范考试,考不过要补考。补考不过再补考,直到考过为止...... 困惑3:审查标准难以统一。 不同审查者的关注点不同,缺乏统一的审查标准,导致代码质量波动较大? 如果你深受以上痛点困扰,那么本文将为你带来一套完整的解决方案——通过 GitLab 与 Coco AI 的深度集成,实现智能化、自动化的代码审查流程。 让 AI 助手在每次代码提交时自动检测代码风格问题、安全漏洞和潜在 bug,为你的代码质量把好第一道关。 unsetunset二、完整实现步骤unsetunset 2.0 前置条件 * 1、

By Ne0inhk
JDK 24里程碑:虚拟线程重大升级,要用虚拟线程请务必用JDK24

JDK 24里程碑:虚拟线程重大升级,要用虚拟线程请务必用JDK24

🧑 博主简介:ZEEKLOG博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可关注公众号 “ 心海云图 ” 微信小程序搜索“历代文学”)总架构师,16年工作经验,精通Java编程,高并发设计,分布式系统架构设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。 🤝商务合作:请搜索或扫码关注微信公众号 “ 心海云图 ” 文章目录 * JDK 24里程碑:虚拟线程重大升级,要用虚拟线程请务必用JDK24 * 摘要 * 一、 问题根源:虚拟线程与synchronized的先天冲突 * 1.1 虚拟线程的调度模型 * 1.2 `synchronized`

By Ne0inhk
【AI应用开发工程师】-分享Java 转 AI成功经验

【AI应用开发工程师】-分享Java 转 AI成功经验

Java 转 AI:别再死磕书本了,老司机带你飞! 文章目录 * Java 转 AI:别再死磕书本了,老司机带你飞! * ⭐AI 大模型应用开发全方位成长路线⭐ * 一、Java 老兵的 AI 转型焦虑:书本,你真的跟不上时代了! * 二、AI 导师,你的专属学习外挂! * 三、抱紧大腿,和 AI 大佬一起成长! * 四、拓展方案一:开源社区,你的 AI 练兵场! * 五、拓展方案二:小步快跑,项目实战是王道! * 六、拓展方案三:知识管理,告别“学了就忘”的魔咒! * 七、总结:转型 AI,一场充满乐趣的冒险!

By Ne0inhk