在 Spring AOP 中,通知(Advice)的顺序是由通知的类型和声明的顺序决定的。Spring AOP 提供了几种不同类型的通知,包括前置通知、后置通知、环绕通知、异常通知和最终通知。它们的执行顺序主要依赖于通知的类型和它们在配置中声明的顺序。

通知类型及其执行顺序

  1. 前置通知(@Before):在方法执行前执行。

    • 执行顺序:最先执行。
  2. 环绕通知(@Around):在方法执行前后都能执行,可以控制方法是否被调用。

    • 执行顺序:如果存在 @Around 通知,它会在前置通知之前执行(如果有的话),并且在后置通知和异常通知之前执行。@Around 通知可以选择是否调用目标方法,并在调用前后执行自定义的逻辑。
  3. 后置通知(@AfterReturning):在方法成功执行后(即没有抛出异常时)执行。

    • 执行顺序:在方法执行完毕后(目标方法调用返回之后)执行,紧随环绕通知后。
  4. 异常通知(@AfterThrowing):在方法抛出异常时执行。

    • 执行顺序:仅在目标方法抛出异常时执行,位于后置通知之后。
  5. 最终通知(@After):无论方法是否抛出异常,都会执行。

    • 执行顺序:最后执行,不管目标方法是否成功或抛出异常。

执行顺序的总结:

  1. 前置通知(@Before):最先执行。
  2. 环绕通知(@Around):在前置通知之后,目标方法执行之前。环绕通知的 proceed() 方法调用才会触发目标方法。
  3. 后置通知(@AfterReturning):在目标方法成功执行后执行。
  4. 异常通知(@AfterThrowing):仅在目标方法抛出异常时执行,位于后置通知之后。
  5. 最终通知(@After):无论方法是否成功执行或抛出异常,都会最后执行。

注意事项:

  • @Around 通知的执行顺序要比其他通知更为灵活,因为它可以选择是否执行目标方法,并且决定目标方法执行的时机。
  • 如果 @Around 通知中没有显式调用 proceed(),目标方法是不会被调用的,因此后续的通知(如后置通知、异常通知等)将不会执行。

示例代码:

@Aspect
@Component
public class MyAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void beforeAdvice() {
        System.out.println("Before method execution");
    }

    @Around("execution(* com.example.service.*.*(..))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Around before method execution");
        Object result = joinPoint.proceed();
        System.out.println("Around after method execution");
        return result;
    }

    @AfterReturning("execution(* com.example.service.*.*(..))")
    public void afterReturningAdvice() {
        System.out.println("After method execution (if successful)");
    }

    @AfterThrowing("execution(* com.example.service.*.*(..))")
    public void afterThrowingAdvice() {
        System.out.println("After method threw an exception");
    }

    @After("execution(* com.example.service.*.*(..))")
    public void afterAdvice() {
        System.out.println("After method execution (always)");
    }
}

执行顺序会是:

  1. beforeAdvice (前置通知)
  2. aroundAdvice 的前半部分(环绕通知,在目标方法之前)
  3. 目标方法的执行
  4. aroundAdvice 的后半部分(环绕通知,在目标方法之后)
  5. afterReturningAdvice(后置通知,如果没有抛出异常)
  6. afterAdvice(最终通知,始终执行)

如果目标方法抛出异常:

  1. beforeAdvice (前置通知)
  2. aroundAdvice 的前半部分(环绕通知,在目标方法之前)
  3. 异常发生
  4. afterThrowingAdvice(异常通知)
  5. afterAdvice(最终通知,始终执行)

总结:

Spring AOP 的通知顺序是通过通知类型以及它们的声明顺序来决定的。通过合理配置不同类型的通知,可以实现灵活的 AOP 行为。


今夜有点儿凉
37 声望1 粉丝

今夜有点儿凉,乌云遮住了月亮。