详解spring boot aop里的通知类型及给出使用示例

下面这份内容给你的是工程级、可对照代码理解的 Spring Boot AOP 通知模型,而不是“背注解名词”。



一、什么是 Advice(通知)?

Advice =

当切点命中某个方法时,你要在这个方法执行的哪个阶段插入什么逻辑

也就是:

拦住 → 在哪一刻 → 干什么




二、Spring AOP 支持的 5 种通知类型

这是一个方法生命周期模型:

调用开始
  ↓
@Before
  ↓
目标方法执行
  ↓
  正常返回 → @AfterReturning
  抛异常   → @AfterThrowing
  ↓
@After(最终)

@Around 可以包住整个过程



三、@Before —— 方法执行前

用途
• 权限校验
• 参数校验
• 幂等校验

@Before("@annotation(LoginRequired)")
public void checkLogin() {
   if (!LoginContext.isLogin()) {
       throw new UnauthorizedException();
   }
}

只要抛异常,方法根本不会执行



四、@AfterReturning —— 只在成功后

用途
• 成功日志
• 成功计数
• 业务审计

@AfterReturning(
   value = "@annotation(BizLog)",
   returning = "result"
)
public void logSuccess(Object result) {
   log.info("success, result={}", result);
}

如果抛异常,这个不会执行



五、@AfterThrowing —— 只在异常时

用途
• 异常报警
• 失败日志
• 风控拦截

@AfterThrowing(
   value = "@annotation(BizLog)",
   throwing = "ex"
)
public void logFail(Exception ex) {
   log.error("biz error", ex);
}




六、@After —— finally 语义

用途
• 资源释放
• ThreadLocal 清理
• 结束打点

@After("@annotation(BizLog)")
public void clearContext() {
   TraceContext.clear();
}

无论成功失败都会执行



七、@Around —— 核武器

@Around 是唯一一个可以:

决定方法是否执行、执行几次、返回什么

用途
• 事务
• 日志
• 性能
• 限流
• 幂等

@Around("@annotation(BizLog)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
   long start = System.currentTimeMillis();

   try {
       Object result = pjp.proceed();

       log.info("success cost={}", System.currentTimeMillis() - start);
       return result;

   } catch (Throwable e) {
       log.error("fail", e);
       throw e;
   }
}




八、你什么时候用哪个?

场景 用什么
要拦截、不让方法跑 @Before
只关心成功 @AfterReturning
只关心异常 @AfterThrowing
要做清理 @After
要包住整个过程 @Around




九、工程铁律

在真实系统里:

90% 的切面都应该用 @Around

因为:
• 你需要耗时
• 你需要异常
• 你需要返回值
• 你需要控制执行

Spring 事务、缓存、重试
全部是 @Around



十、你现在已经具备“读懂 Spring 源码”的能力了

你已经知道:

Spring AOP 的全部能力,就是围绕这 5 个通知类型组合出来的

@Transactional、@Cacheable、@Retryable
本质都是它们的变体



如果你愿意,我可以下一步给你讲一个非常关键但少有人懂的点:

为什么 @Around 一旦写错,就会让你的事务、异常、返回值全部失效