springspring-bootaopcontroller-advice

After an exception is thrown (handled by controller advice), will the globally executed aop program also terminate?


controller:

@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * @RequestLog records logs annotation
     */
    @PostMapping("/t1")
    @RequestLog(description = "log test")
    public ApiResult<?> t1(@RequestBody T1VO t1) {
        // FillDataException thrown during execution
        // throw new FillDataException()
    }
}

GlobalExceptionHandler:

@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * If FillDataException is thrown in the controller, this method will be executed
     */
    @ExceptionHandler(FillDataException.class)
    public ApiResult<?> fillDataException(FillDataException e) {
        printExceptionStackTrace(e);
        String defaultMessage = e.getMessage();
        return ApiResult.response(ResultEnum.DATA_INVALID,defaultMessage);
    }
}

aop program that records logs after a client request ends:

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(com.test.common.log.RequestLog)")
    public void logPointCut() {
    }
    
    /**
     * If FillDataException is thrown in the controller, this method will not be executed
     */
    @AfterReturning(value = "logPointCut()",returning = "ret")
    public void logAfter(JoinPoint joinPoint, Object ret) {
        //Processing response results
        if (ret instanceof ApiResult) {
            //logs save to database 
        }
    }

}

After an exception is thrown (handled by controller advice), why does the aop program not execute? How to solve it?


Solution

  • After an exception is thrown, aop @AfterReturning will not be executed. You can use @AfterThrowing or @Around to handle it.

    @AfterThrowing

    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void logThrowable(JoinPoint joinPoint, Throwable e) {
        ApiResult<?> apiResult = GlobalExceptionHandler.handleException((Exception) e);
        saveLog(joinPoint,apiResult);
    }
    

    @Around

    @Around(value = "logPointCut()")
    public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
        Exception e = null;
        try {
            return pjp.proceed();
        } catch (Throwable throwable) {
            e = (Exception) throwable;
            throw throwable;
        } finally {
            if (e != null) {
                ApiResult<?> apiResult = GlobalExceptionHandler.handleException(e);
                saveLog(pjp,apiResult);
            }
        }
    }