大家好,我是锋哥。今天分享关于【Spring-AOP通知和执行顺序?】面试题。希望对大家有帮助;
Spring-AOP通知和执行顺序?
在 Spring AOP 中,通知(Advice)是指横切逻辑的代码部分,它会在指定的连接点(JoinPoint)执行之前、之后或异常抛出时执行。Spring AOP 的通知有几种类型,执行顺序主要取决于通知类型和配置的顺序。
通知类型
- 前置通知(@Before):在目标方法执行之前调用。
- 后置通知(@After):在目标方法执行之后调用(无论是否抛出异常)。
- 返回通知(@AfterReturning):在目标方法成功执行之后调用,即目标方法没有抛出异常时。
- 异常通知(@AfterThrowing):在目标方法抛出异常之后调用。
- 环绕通知(@Around):可以控制目标方法的执行,既可以在方法执行之前做一些处理,也可以在执行之后做一些处理,并可以选择是否执行目标方法。
执行顺序
在 Spring AOP 中,通知的执行顺序通常是这样的:
- 环绕通知(
@Around
): 在所有其他通知之前执行。环绕通知可以控制目标方法是否执行,它是最强的通知,可以在执行目标方法之前和之后做处理。 - 前置通知(
@Before
): 在目标方法执行之前执行。 - 目标方法: 真正执行的方法。
- 后置通知(
@After
): 在目标方法执行之后调用,不论目标方法是否抛出异常。 - 返回通知(
@AfterReturning
): 在目标方法成功返回后执行。 - 异常通知(
@AfterThrowing
): 在目标方法抛出异常时执行。
示例
假设有如下的通知配置:
@Aspect
public class MyAspect {
@Before("execution(* com.example.MyService.*(..))")
public void before() {
System.out.println("Before method execution");
}
@After("execution(* com.example.MyService.*(..))")
public void after() {
System.out.println("After method execution");
}
@AfterReturning("execution(* com.example.MyService.*(..))")
public void afterReturning() {
System.out.println("After method returns successfully");
}
@AfterThrowing("execution(* com.example.MyService.*(..))")
public void afterThrowing() {
System.out.println("After method throws exception");
}
@Around("execution(* com.example.MyService.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Around before method execution");
Object result = pjp.proceed();
System.out.println("Around after method execution");
return result;
}
}
执行顺序
- 环绕通知(
@Around
): 会先执行Around before method execution
,然后调用pjp.proceed()
来执行目标方法,最后执行Around after method execution
。 - 前置通知(
@Before
): 如果@Around
没有阻止目标方法的执行,那么会执行前置通知。 - 目标方法: 执行目标方法。
- 后置通知(
@After
): 执行后置通知。 - 返回通知(
@AfterReturning
): 如果目标方法执行没有抛出异常,会执行返回通知。 - 异常通知(
@AfterThrowing
): 如果目标方法执行抛出了异常,会执行异常通知。
重点注意:
- 环绕通知(
@Around
)有控制目标方法是否执行的能力,它包裹着整个方法的执行逻辑。 - 如果环绕通知不调用
pjp.proceed()
,则目标方法不会执行。 - 只有在目标方法正常执行(没有抛出异常)时,返回通知和后置通知才会执行。
- 如果目标方法抛出了异常,异常通知会执行,而返回通知不会执行。