博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。
② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。
③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。
进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。
群公告里还有全网大赛约稿汇总/博客提效工具集/CSDN自动化运营脚本 有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。
文章目录
- [Spring Boot AOP(三) 通知执行链源码解析](#Spring Boot AOP(三) 通知执行链源码解析)
-
- [1. 执行链概述](#1. 执行链概述)
- [2. Advisor 链与通知统一处理](#2. Advisor 链与通知统一处理)
-
- [Mermaid 流程图:Advisor 链构建](#Mermaid 流程图:Advisor 链构建)
- [3. MethodInterceptor 执行流程](#3. MethodInterceptor 执行流程)
-
- [3.1 ReflectiveMethodInvocation 核心源码](#3.1 ReflectiveMethodInvocation 核心源码)
- [3.2 执行逻辑说明](#3.2 执行逻辑说明)
- [Mermaid 流程图:MethodInterceptor 调用链](#Mermaid 流程图:MethodInterceptor 调用链)
- [4. 不同通知类型执行链示意](#4. 不同通知类型执行链示意)
- [5. 环绕通知执行链深入解析](#5. 环绕通知执行链深入解析)
-
- [Mermaid 流程图:环绕通知链执行](#Mermaid 流程图:环绕通知链执行)
- [6. 多 Advisor 链组合示例](#6. 多 Advisor 链组合示例)
- [7. ReflectiveMethodInvocation 执行链源码示意](#7. ReflectiveMethodInvocation 执行链源码示意)
- [8. 本文总结](#8. 本文总结)
- 结束语

Spring Boot AOP(三) 通知执行链源码解析
1. 执行链概述
在 Spring AOP 中,一个方法可能对应 多个切面(Aspect) 和 多个通知(Advice) 。Spring 使用 Advisor 链 + MethodInterceptor 链 来统一管理这些通知,使方法执行时按顺序执行各类通知。
核心概念
| 概念 | 说明 |
|---|---|
| Advisor | 切面 + 切入点 + 通知的组合对象 |
| Advice | 切面中具体执行的操作,例如 @Before、@After、@Around |
| MethodInterceptor | AOP 的统一调用接口,所有 Advice 最终都转换为 MethodInterceptor |
| ReflectiveMethodInvocation | 方法调用封装类,负责顺序调用 Advisor 链 |
Spring AOP 的通知最终都会被封装为 MethodInterceptor ,执行链由 ReflectiveMethodInvocation 管理。
2. Advisor 链与通知统一处理
在 Spring 中,多个切面可能作用于同一个方法。Spring 会将所有切面对应的通知 排序后加入 Advisor 链:
- 收集匹配的切面
- 将切面中的 Advice 转换为 MethodInterceptor
- 按 @Order 或实现 Ordered 接口排序
- 构建 ReflectiveMethodInvocation 执行链
Mermaid 流程图:Advisor 链构建
扫描 Bean 切面 匹配切入点 收集匹配的通知 Advice 转换为 MethodInterceptor 按顺序构建 ReflectiveMethodInvocation 链
3. MethodInterceptor 执行流程
3.1 ReflectiveMethodInvocation 核心源码
核心方法:proceed()
java
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.method.invoke(this.target, this.arguments);
}
Object interceptorOrAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrAdvice instanceof MethodInterceptor) {
return ((MethodInterceptor) interceptorOrAdvice).invoke(this);
} else {
return proceed();
}
}
3.2 执行逻辑说明
currentInterceptorIndex控制当前执行的通知- 如果到达链尾,则调用目标方法
- 否则,将当前通知强转为 MethodInterceptor 并调用
- 每个环绕通知内部可以调用
proceed()执行下一环节
Mermaid 流程图:MethodInterceptor 调用链
proceed] B --> C[@Before 前置通知] C --> D[@Around 环绕通知 - 前半部分] D --> E[proceed 递归调用] E --> F[目标方法执行] F --> G[@Around 环绕通知 - 后半部分] G --> H[@AfterReturning 返回通知
或
@AfterThrowing 异常通知] H --> I[@After 后置通知] I --> J[返回客户端] style A fill:#BBDEFB style B fill:#FFF9C4 style C fill:#C8E6C9 style D fill:#FFE0B2 style F fill:#FFCDD2 style H fill:#FFCCBC style J fill:#E1BEE7
4. 不同通知类型执行链示意
| 通知类型 | 转换为 MethodInterceptor | 执行顺序 |
|---|---|---|
| 前置通知 @Before | MethodBeforeAdviceInterceptor | 最先执行 |
| 环绕通知 @Around | AroundAdviceInterceptor | 可环绕目标方法 |
| 返回通知 @AfterReturning | AfterReturningAdviceInterceptor | 目标方法成功返回后执行 |
| 异常通知 @AfterThrowing | AfterThrowingAdviceInterceptor | 目标方法异常时执行 |
| 后置通知 @After | AfterAdviceInterceptor | 最后执行,无论成功/异常 |
5. 环绕通知执行链深入解析
环绕通知最灵活,可以完全控制方法执行:
java
@Around("execution(* com.example.service..*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知前逻辑");
Object result = pjp.proceed();
System.out.println("环绕通知后逻辑");
return result;
}
Mermaid 流程图:环绕通知链执行
方法调用 环绕通知1前逻辑 环绕通知2前逻辑 目标方法执行 环绕通知2后逻辑 环绕通知1后逻辑 返回调用方
6. 多 Advisor 链组合示例
java
@Aspect
@Component
@Order(1)
public class LoggingAspect {
@Before("execution(* com.example.service..*.*(..))")
public void before(JoinPoint jp) {
System.out.println("日志前置: " + jp.getSignature());
}
}
@Aspect
@Component
@Order(2)
public class TransactionAspect {
@Around("execution(* com.example.service..*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("事务开始");
Object result = pjp.proceed();
System.out.println("事务提交");
return result;
}
}
@Aspect
@Component
@Order(3)
public class MetricsAspect {
@AfterReturning(pointcut = "execution(* com.example.service..*.*(..))", returning = "result")
public void afterReturning(JoinPoint jp, Object result) {
System.out.println("性能监控: " + jp.getSignature() + ", 返回: " + result);
}
}
多切面执行顺序示意
7. ReflectiveMethodInvocation 执行链源码示意
是 否 proceed 方法调用 获取当前索引的 MethodInterceptor 索引是否到达链尾? 执行目标方法 method.invoke 执行当前拦截器 interceptor.invoke this 拦截器内部调用 proceed 返回结果 逐层返回到调用方
8. 本文总结
- Spring AOP 统一将所有通知封装为 MethodInterceptor
ReflectiveMethodInvocation负责 链式执行所有通知- 环绕通知可以完全控制目标方法执行,其他通知按 Advisor 链顺序执行
- 多切面组合执行顺序由
@Order或Ordered接口控制 - Mermaid 图直观展示了 Advisor 链、方法调用链和环绕通知执行顺序
这一篇是 源码级、流程图丰富、示例全面 的第三篇,紧接第二篇的代理机制,完整衔接整个系列。
下一步可以写 第四篇:Spring Boot /error 与 BasicErrorController 源码解析 或你希望继续写 异常与 AOP 结合的执行顺序 这一主题,你希望我直接写哪一个?
结束语

👨💻 关于我
持续学习 | 追求真我
如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。
感谢订阅专栏 三连文章

掘金点击访问Qiuner CSDN点击访问Qiuner GitHub点击访问Qiuner Gitee点击访问Qiuner
| 专栏 | 简介 |
|---|---|
| 📊 一图读懂系列 | 图文并茂,轻松理解复杂概念 |
| 📝 一文读懂系列 | 深入浅出,全面解析技术要点 |
| 🌟持续更新 | 保持学习,不断进步 |
| 🎯 人生经验 | 经验分享,共同成长 |
你好,我是Qiuner. 为帮助别人少走弯路而写博客
如果本篇文章帮到了你 不妨点个赞 吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。
代码都在Github或Gitee上,如有需要可以去上面自行下载。记得给我点星星哦😍
如果你遇到了问题,自己没法解决,可以去我掘金评论区问。CSDN评论区和私信消息看不完 掘金消息少一点.
| 上一篇推荐 | 链接 |
|---|---|
| Java程序员快又扎实的学习路线 | 点击该处自动跳转查看哦 |
| 一文读懂 AI | 点击该处自动跳转查看哦 |
| 一文读懂 服务器 | 点击该处自动跳转查看哦 |
| 2024年创作回顾 | 点击该处自动跳转查看哦 |
| 一文读懂 ESLint配置 | 点击该处自动跳转查看哦 |
| 老鸟如何追求快捷操作电脑 | 点击该处自动跳转查看哦 |
| 未来会写什么文章? | 预告链接 |
|---|---|
| 一文读懂 XX? | 点击该处自动跳转查看哦 |
| 2025年终总结 | 点击该处自动跳转查看哦 |
| 一图读懂 XX? | 点击该处自动跳转查看哦 |
