Skip to content

Spring 通知有哪些类型? ​

  • 标签:后端、Spring

🏛 业务架构师 ​

Spring AOP 有五种通知类型,我按一次方法调用的时序讲,并附上业务适用场景:

  • @Before(前置通知):方法执行前。用于权限校验、参数补全、防重检查——把非法请求拦在业务执行前,省下游资源;
  • @After(后置通知):方法执行后(无论成功失败),类似 finally 的清理场景;
  • @AfterReturning(返回通知):成功返回后。用于结果加工、成功埋点;
  • @AfterThrowing(异常通知):抛异常后。用于异常告警、失败留痕(接 Sentry/钉钉机器人);
  • @Around(环绕通知):包裹整个方法执行,可控制是否执行目标、改写入参返回值。功能最全:限流、耗时监控、缓存、幂等都靠它。

实战经验两条:

  1. 能用 @Before/@AfterReturning 就别用 @Around。环绕通知要自己处理 try/finally 和 proceed 异常,写错就吞异常或漏调用,是线上事故高发点。通知类型选"表达力刚好够"的,错误面最小;
  2. 异常通知里只做记录不做兜底。在切面里 catch 住业务异常返回默认值,会让上游误判成功,造成静默资损。降级逻辑要有明确业务评审。

架构治理角度:公司级切面(监控、审计、鉴权)统一封装成 starter,业务方只加注解。通知类型是工具,统一供给才是资产化。

🏗 系统架构师 ​

五种:

  • @Before:方法执行前(鉴权、参数校验);
  • @After:finally 语义,成败都执行(清理资源);
  • @AfterReturning:正常返回后(结果加工、审计);
  • @AfterThrowing:抛异常后(异常告警上报);
  • @Around:包裹全流程,显式控制是否与何时调用 proceed()——最强大也最危险。

我的使用纪律:

  1. 能用具体通知就不用 Around——Around 忘调 proceed、吞异常、改返回值的自由度太大,是切面事故的主要来源;
  2. 多切面叠加用 @Order 显式声明顺序(值越小越外层),否则「事务提交后才写审计」还是「先审计后提交」全凭运气;
  3. 切面内不写业务分支逻辑,只做转发、包装、度量——切面一旦带业务状态,全服务的行为一致性就失控了。

💻 全栈开发专家 ​

五种:

java
@Aspect
@Component
public class DemoAspect {
    @Before("pointcut()")                       // 1. 方法前
    public void before(JoinPoint jp) { }

    @After("pointcut()")                        // 2. 类似 finally,正常异常都执行
    public void after(JoinPoint jp) { }

    @AfterReturning(value = "pointcut()", returning = "ret")  // 3. 正常返回后
    public void afterRet(Object ret) { }

    @AfterThrowing(value = "pointcut()", throwing = "e")      // 4. 抛异常后
    public void afterEx(Exception e) { }

    @Around("pointcut()")                       // 5. 环绕:前四个的超集
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            return pjp.proceed();               // 放行目标方法,只调一次
        } finally {
            metrics.record(pjp.getSignature(), System.currentTimeMillis() - start);
        }
    }
}

实践偏好:统一用 @Around 一个打天下——耗时统计、返回值改写、异常转译都能做,控制流清晰。铁律:proceed() 只调一次,重复调用等于业务执行两遍(幂等切面里见过这种事故)。

同一切面内执行顺序:Around 前置 → Before → 目标方法 → AfterReturning/AfterThrowing → After → Around 后置。多切面按 @Order 值小的在外层,洋葱圈模型记不错。