Java Spring Boot中的AOP支持一个Pointcut包含另一个切点的情况,可以使用多个Around Advice处理,并且可以通过@Order注解定义优先级。以下是示例代码:
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* com.example.demo.service.UserService.*(..))")
public void userPointcut() {}
@Pointcut("execution(* com.example.demo.service.OrderService.*(..))")
public void orderPointcut() {}
@Around("userPointcut() || orderPointcut()")
@Order(1)
public Object userOrderAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// User和Order Pointcut的处理逻辑1
Object result = null;
try {
result = joinPoint.proceed();
// User和Order Pointcut的处理逻辑2
} catch (Exception e) {
// User和Order Pointcut的异常处理逻辑
throw e;
}
return result;
}
@Around("userPointcut() && !orderPointcut()")
@Order(2)
public Object userAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// User Pointcut的处理逻辑1
Object result = null;
try {
result = joinPoint.proceed();
// User Pointcut的处理逻辑2
} catch (Exception e) {
// User Pointcut的异常处理逻辑
throw e;
}
return result;
}
@Around("!userPointcut() && orderPointcut()")
@Order(3)
public Object orderAroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// Order Pointcut的处理逻辑1
Object result = null;
try {
result = joinPoint.proceed();
// Order Pointcut的处理逻辑2
} catch (Exception e) {
// Order Pointcut的异常处理逻辑
throw e;
}
return result;
}
@AfterThrowing(pointcut = "userPointcut() || orderPointcut()", throwing = "ex")
public void exceptionAdvice(Exception ex) {
// 异常处理逻辑
}
}
在上述代码中,我们定义了两个切点,分别是userPointcut和orderPointcut,并定义了三个Around Advice,分别对应不同的处理逻辑。其中,userOrderAroundAdvice方法同时处理了userPointcut和orderPointcut,userAroundAdvice方法只处理userPointcut,而orderAroundAdvice方法只处理orderPointcut。通过在Around Advice上使用逻辑运算符实现不同的切点组合。同时,我们在每个Around Advice上使用@Order注解指定其优先级。如果切点包含关系复杂,建议使用@Order注解来明确指定优先级,以确保处理逻辑的正确性和一致性。最后,我们还定义了一个@AfterThrowing Advice用于捕捉异常,并实现异常处理逻辑。
执行过程如下:
当执行UserService或OrderService的任何方法时,会触发userPointcut或orderPointcut切点。
如果同时符合userPointcut和orderPointcut切点,则会依次调用userOrderAroundAdvice方法。
userOrderAroundAdvice方法会执行其中的处理逻辑1,并调用proceed()方法,执行目标方法,即UserService或OrderService的方法。
如果目标方法抛出异常,会被try-catch语句捕捉,并执行其中的异常处理逻辑。
如果目标方法正常执行完毕,会返回结果给userOrderAroundAdvice方法。
userOrderAroundAdvice方法会执行其中的处理逻辑2,然后返回结果。
如果只符合userPointcut切点,则会依次调用userAroundAdvice方法。
userAroundAdvice方法会执行其中的处理逻辑1,并调用proceed()方法,执行目标方法,即UserService的方法。
如果目标方法抛出异常,会被try-catch语句捕捉,并执行其中的异常处理逻辑。
如果目标方法正常执行完毕,会返回结果给userAroundAdvice方法。
userAroundAdvice方法会执行其中的处理逻辑2,然后返回结果。
如果只符合orderPointcut切点,则会依次调用orderAroundAdvice方法。
orderAroundAdvice方法会执行其中的处理逻辑1,并调用proceed()方法,执行目标方法,即OrderService的方法。
如果目标方法抛出异常,会被try-catch语句捕捉,并执行其中的异常处理逻辑。
如果目标方法正常执行完毕,会返回结果给orderAroundAdvice方法。
orderAroundAdvice方法会执行其中的处理逻辑2,然后返回结果。
如果任何一个方法抛出异常,都会被@AfterThrowing Advice捕捉到,并执行其中的异常处理逻辑。
在示例代码中,我们使用了逻辑运算符实现了不同的切点组合,并通过@Order注解明确了处理逻辑的优先级。同时,通过try-catch语句,我们可以捕捉异常,以确保程序的正确性和稳定性。最后,通过@AfterThrowing注解,我们可以捕捉异常,并实现异常处理逻辑。