web-dev-qa-db-ja.com

Spring AOP + Aspectjによる例外処理

私のプロジェクトには、基本的にPOJOであるドメインレイヤーと、ドメインレイヤーの上にあるSpringコントローラー/サービスレイヤーがあります。また、サービスとドメインの間にあるAOPレイヤーもあります。

私のドメインレイヤーは、現在サービスレイヤーで処理されているビジネス例外をスローしています。

ただし、ドメインレイヤーからスローされた例外がAOPレイヤーで処理されるように変更したいと思います。 AOPレイヤーは、ある種のエラー応答を返し、それをSpring Controller/Webサービスレイヤーに送り返します。

IBizResponseを作成し、その2つのサブクラス/インターフェイスをおそらくSuccessResponseとErrorResponseにして、ドメインレイヤーメソッドにIBizResponseを返すようにすることができます。ただし、AOPがErrorResponseオブジェクトをサービスレイヤーに返すようにする方法を理解できません。

6
Nitish Raj

例外処理の場合にエラー応答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());
    }
}

以下のような例外処理用に別のクラスを定義しました。

@ControllerAdvice
public class ExceptionLogAdvice {

    @ExceptionHandler(InternalServerException.class)
    @ResponseStatus(HttpStatus.BAD_GATEWAY)
    @ResponseBody
    public ResponseEntity<Object> handleValidationException(final InternalServerException internalServerException){

        ErrorResponseDTO dto = constructErrorResponse(internalServerException);
        return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body(dto);
    }
}

実際のコードを共有できないため、コードを少しツイートしました。コンセプトを明確にしたいと思います。

4
Linz

https://docs.spring.io/spring/docs/4.1.0.RELEASE/spring-framework-reference/htmlsingle/#aop-introduction-defn のアドバイスをスローした後のセクションを参照してください。

スロー後のアドバイスは、一致したメソッドの実行が例外をスローして終了したときに実行されます。 @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) {
       // ...
     }

}
7
vinayknl

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;
    }
}
1
Nitish Raj