Spring AOP 顺序问题:切面都生效了,不代表顺序对 Spring AOP 顺序问题切面都生效了不代表顺序对一、AOP 问题不一定是切面没执行Spring AOP 排障时很多人先看切面是否生效。日志打印了、注解识别了、代理也创建了于是觉得没问题。但生产里更隐蔽的问题是多个切面都执行了只是顺序不对。事务、鉴权、限流、日志、幂等、审计的顺序一错行为就会变得很奇怪。比如日志切面包在事务外面记录的耗时包含事务提交幂等切面在参数校验前执行缓存了非法请求鉴权在限流后执行让未授权请求也消耗限流额度。切面不是越多越好顺序才是关键。二、多个切面会形成调用栈切面顺序决定谁在外层、谁在内层。flowchart TD A[请求进入代理] -- B[鉴权切面] B -- C[限流切面] C -- D[事务切面] D -- E[业务方法] E -- F[事务提交] F -- G[审计记录]外层切面更早进入、更晚退出。理解这个调用栈才能判断异常、耗时和事务边界。三、用 Order 明确顺序下面是一个简单示例。Aspect Order(10) public class AuthAspect { // 鉴权逻辑 } Aspect Order(20) public class RateLimitAspect { // 限流逻辑 }不要依赖默认顺序。不同配置、不同 Bean 注册方式、不同自动配置都可能影响实际顺序。关键切面必须显式声明。四、切面顺序要按业务语义设计通常鉴权应该早于限流避免无效请求消耗业务额度。参数校验应该早于幂等落库避免非法请求留下状态。事务应该包住真正需要原子性的业务而不是把外部 RPC 也放进事务里。异常处理也要看顺序。外层切面能捕获内层异常内层切面看不到外层后处理。审计日志如果要记录最终结果就应该能观察到业务异常和事务结果。测试要覆盖切面组合。单测某个切面容易通过多个切面叠加后才出现问题。可以写集成测试验证调用顺序、异常传播和事务回滚。最后切面不要滥用。AOP 适合横切关注点不适合隐藏核心业务流程。过多逻辑藏在切面里会让代码阅读者看不见真实执行路径。还要注意自调用问题。同一个类内部方法互相调用时通常不会经过代理切面不会生效。很多事务、缓存、审计问题不是注解写错而是调用路径绕过了代理。排查时要确认调用是否来自代理对象。切面里的异常处理要克制。外层切面如果吞掉异常事务切面可能无法感知失败最终导致不该提交的事务被提交。记录日志可以改变异常语义要非常谨慎。最后切面执行顺序要写进团队约定。新加一个切面时必须说明它应该位于鉴权、事务、限流、审计的哪一层。否则系统运行几年后顺序会变成没人敢动的隐形复杂度。还要区分 Spring AOP 和 AspectJ 的能力边界。Spring AOP 基于代理主要拦截方法调用对构造器、字段访问、final 方法、内部调用的支持有限。不了解边界就会以为注解写上就一定生效。排查时可以把代理类型和实际 Bean 打出来。JDK 动态代理、CGLIB 代理、目标类方法可见性都会影响行为。不要只看注解存在要看运行时调用对象到底是谁。最后AOP 变更要做回归测试。切面一改影响的是所有匹配 pointcut 的方法。pointcut 写得过宽可能把后台任务、健康检查或内部补偿逻辑也包进去问题会很隐蔽。五、总结Spring AOP 排障不能只确认切面是否生效还要确认顺序是否符合业务语义。鉴权、限流、事务、幂等、审计的外内层关系会直接影响系统行为。关键切面要显式排序并用集成测试验证组合效果。