通过Spring AOP + Aspectj进行exception处理

在我的项目中,我有一个域层,它基本上是POJO和一个位于域层顶部的Spring控制器/服务层。 我还有一个位于服务和域之间的AOP层。

我的域层正在抛出业务exception,这些exception现在正在服务层中处理。

但是我想更改它,以便在AOP层中处理从域层抛出的exception。 AOP层会出现某种错误响应并将其发送回Spring控制器/ Web服务层。

我可以创建一个IBizResponse并创建它的两个子类/接口,也许是SuccessResponse和ErrorResponse,并使我的域层方法返回IBizResponse。 但是,我无法弄清楚如何使AOP将ErrorResponse对象返回到服务层。

我遇到了同样的情况,我必须在任何exception处理的情况下返回错误响应DTO。 在@Aspect类中,

@Aspect @Component public class MyAspect{ private static final Logger LOGGER = LoggerFactory.getLogger(MyAspect.class); @Pointcut("execution(* com.linda.dao.strategy.*.*(..))") public void strategyMethods() { } @Pointcut("execution(* com.linda.controller.*.*(..)) || execution(* com.linda.Manager.*(..))") public void controllerMethods(){ } @Around("strategyMethods()") public Object profileStrategyMethods(ProceedingJoinPoint pjp) throws Throwable { long start = System.currentTimeMillis(); Object output = null; LOGGER.info("Class:"+pjp.getTarget().getClass()+" entry -> method ->"+pjp.getSignature().getName()); try{ output = pjp.proceed(); long elapsedTime = System.currentTimeMillis() - start; LOGGER.info("Method execution time: " + elapsedTime + " milliseconds."); LOGGER.info("Class:"+pjp.getTarget().getClass()+" exit -> method ->"+pjp.getSignature().getName()); }catch(Throwable t){ throw new InternalServerException(t.getMessage()); } return output; } @AfterThrowing(pointcut="execution(* com.linda.dao.strategy.*.*(..)) || execution(* com.linda.controller.*.*(..)) || execution(* com.linda.Manager.*(..))",throwing = "ex") public void doRecoveryActions(JoinPoint joinPoint, Throwable ex) { Signature signature = joinPoint.getSignature(); String methodName = signature.getName(); String stuff = signature.toString(); String arguments = Arrays.toString(joinPoint.getArgs()); LOGGER.error("Write something in the log... We have caught exception in method: " + methodName + " with arguments " + arguments + "\nand the full toString: " + stuff + "\nthe exception is: " + ex.getMessage()); } 

为下面的exception处理定义了另一个类:

 @ControllerAdvice 

公共类ExceptionLogAdvice {

 @ExceptionHandler(InternalServerException.class) @ResponseStatus(HttpStatus.BAD_GATEWAY) @ResponseBody public ResponseEntity handleValidationException(final InternalServerException internalServerException){ ErrorResponseDTO dto = constructErrorResponse(internalServerException); return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(dto); } 

}

由于我无法共享实际代码,因此略微推文。 希望我明确这个概念。

请参阅https://docs.spring.io/spring/docs/4.1.0.RELEASE/spring-framework-reference/htmlsingle/#aop-introduction-defn的投掷后建议部分

抛出建议运行时,匹配的方法执行通过抛出exception退出。 它是使用@AfterThrowing注释声明的:

例子

 import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing; @Aspect public class AfterThrowingExample { @AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()") public void doRecoveryActions() { // ... } } import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing; @Aspect public class AfterThrowingExample { @AfterThrowing( pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()", throwing="ex") public void doRecoveryActions(DataAccessException ex) { // ... } } 

考虑com.sc.bs.impl。*是业务/域层包,并使用@Around注释在AOP层中拦截它。 代码段:

 @Around("execution(* com.sc.bs.impl..*.*(..))") public Object exceptionHandlerWithReturnType(ProceedingJoinPoint joinPoint) throws Throwable{ try { obj = joinPoint.proceed(); } catch(Exception ex) { throw ex; } }