AOP不同通知的执行顺序详解
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
AOP(面向切面编程)的核心是通过通知(Advice)在目标方法的特定节点植入增强逻辑,Spring AOP作为最常用的实现方案,定义了5种标准通知类型。Spring 5.2.7.RELEASE是执行顺序的关键分水岭,前后版本的@After、@AfterReturning/@AfterThrowing、环绕后置逻辑顺序完全不同,以下分版本、分场景拆解贴合底层源码的完整执行规则。
一、先明确:Spring AOP五大通知类型
- 前置通知(@Before):目标方法执行之前执行,无法阻断目标方法(除非主动抛异常)。
- 后置通知(@After):目标方法执行最终收尾,无论正常返回还是抛异常都会触发,等同于finally代码块。
- 返回通知(@AfterReturning):目标方法正常返回结果后执行,若抛异常则彻底不触发。
- 异常通知(@AfterThrowing):目标方法抛出异常后执行,正常返回则彻底不触发。
- 环绕通知(@Around):最强大的通知,可包裹目标方法全生命周期,手动控制目标方法执行时机,兼具前置、后置、异常处理能力。
核心结论:环绕通知优先级始终高于其他四类通知,全程包裹执行链路;返回/异常通知互斥,5.2.7前后版本仅改变三者的收尾执行顺序,前置逻辑无变化。
二、分版本+分场景:通知完整执行顺序(官方标准)
Spring 5.2.7.RELEASE之前(含):环绕后置逻辑优先于@After,@After优先于返回/异常通知;Spring 5.2.7.RELEASE之后:返回/异常通知优先于@After,@After优先于环绕后置逻辑,以下是详细链路:
版本一:Spring 5.2.7.RELEASE 及之前版本
场景1:目标方法正常执行、无异常抛出
1. 不含环绕通知(纯基础通知)
前置通知(@Before) → 目标方法执行 → 后置通知(@After) → 返回通知(@AfterReturning)
2. 包含环绕通知(完整增强链路)
环绕通知(before前置逻辑) → 前置通知(@Before) → 目标方法执行 → 环绕通知(after后置逻辑) → 后置通知(@After) → 返回通知(@AfterReturning)
场景2:目标方法抛出异常、中断执行
1. 不含环绕通知
前置通知(@Before) → 目标方法抛异常 → 后置通知(@After) → 异常通知(@AfterThrowing)
2. 包含环绕通知
环绕通知(before前置逻辑) → 前置通知(@Before) → 目标方法抛异常 → 环绕通知(after后置逻辑) → 后置通知(@After) → 异常通知(@AfterThrowing)
版本二:Spring 5.2.7.RELEASE 之后版本(含5.2.7)
场景1:目标方法正常执行、无异常抛出
1. 不含环绕通知(纯基础通知)
前置通知(@Before) → 目标方法执行 → 返回通知(@AfterReturning) → 后置通知(@After)
2. 包含环绕通知(完整增强链路)
环绕通知(before前置逻辑) → 前置通知(@Before) → 目标方法执行 → 返回通知(@AfterReturning) → 后置通知(@After) → 环绕通知(after后置逻辑)
场景2:目标方法抛出异常、中断执行
1. 不含环绕通知
前置通知(@Before) → 目标方法抛异常 → 异常通知(@AfterThrowing) → 后置通知(@After)
2. 包含环绕通知
环绕通知(before前置逻辑) → 前置通知(@Before) → 目标方法抛异常 → 异常通知(@AfterThrowing) → 后置通知(@After) → 环绕通知(after后置逻辑)
三、进阶:多切面+优先级的执行顺序
无论Spring版本新旧,多切面优先级规则保持一致:通过@Order(数字)指定优先级,数字越小优先级越高,执行规则遵循外层先入后出原则:
- 前置链路:高优先级切面 → 低优先级切面(外层切面先执行)
- 后置/异常/返回链路:低优先级切面 → 高优先级切面(外层切面后执行)
举例:切面A(Order=1,高优先级)、切面B(Order=2,低优先级),5.2.7之后正常流程顺序:
A环绕before → A前置 → B环绕before → B前置 → 目标方法 → B返回 → B后置 → B环绕after → A返回 → A后置 → A环绕after
四、关键注意事项
- 环绕通知必须调用ProceedingJoinPoint.proceed(),否则目标方法不会执行,后续所有通知都会被阻断。
- 后置通知(@After)最终必然执行,是整个AOP链路的收尾环节,无论目标方法是否异常、是否被环绕拦截。
- 返回通知和异常通知完全互斥,同一目标方法的单次调用中,只会触发其中一种,绝不同时执行。
- Spring AOP仅支持方法级别的切面增强,无法拦截字段访问、构造器执行等操作。
- SpringBoot 2.2.5+ 对应Spring 5.2.7+,AOP顺序默认采用新版规则,升级框架需注意兼容旧版AOP逻辑。
五、极简顺序口诀(分版本记忆)
旧版(5.2.7前):绕前→前→目标→绕后→终后→返/异
新版(5.2.7后):绕前→前→目标→返/异→终后→绕后
通用核心:异常不返回,终后必执行
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
本专栏聚焦Spring全生态体系,从IoC/AOP核心原理入手,覆盖Spring Boot自动配置、事务管理、Web开发等实战内容。拆解循环依赖、动态代理等高频面试难点,助力开发者从入门到精通,打通单体到微服务的技术链路,解决企业级开发痛点,提升架构设计与问题排查能力,成为Java后端进阶的必备技术专栏。
查看9道真题和解析