코딩항해기

[Spring] AOP @AfterThrowing 본문

Spring

[Spring] AOP @AfterThrowing

miniBcake 2024. 10. 20. 15:25

 

@AfterThrowing

사용하면 예외가 발생해 비정상적으로 종료될 때 실행된다.

이 때 어떤 예외가 발생했는지 알고 싶다면 throwing 속성을 사용할 수 있다.

 

다만 말 그대로 예외가 발생한 뒤 실행되기 때문에 예외가 발생하지 않도록 하는 것은 불가능하다. 예외를 다시 던져 전파하거나 특정 예외를 다른 예외의 형태로 변환해줘야할 때 사용된다.

 

다른 형태의 예외로 변환 예시

DataAccessException이 발생하면 ApplicationException을 일으킨다.

@Aspect
@Service
public class MethodExceptionPropagationAspect {
    @AfterThrowing(value = "execution(* *..*ServiceImpl.*(..))", throwing = "e")
    public void endLog(JoinPoint jp, DataAccessException e) {
        throw new ApplicationException(e);
    }
}

 

After Throwing Advice는 예외가 외부로 던져지는 것을 막지는 못하기 때문에 예외가 발생했을 때 꼭 필요한 동작을 수행하게 만든 다음, 예외는 Advice가 없을 때처럼 외부로 던지도록 만들어야 한다. 만약 발생한 예외가 밖으로 던져지는 것을 굳이 막아야 하는 상황이라면 AfterThrowing 대신 Around Advice를 사용하면 된다.

 

 

모든 예외에 대한 처리 예시

throwing 파라미터 명의 타입으로 Throwable이나 Exception이 아닌 특정 예외 타입을 작성하면 해당 타입의 에러만 처리하게 된다. 만약 모든 예외에 접근하고 싶다면  Throwable이나 Exception를 사용할 수 있다.

@Service
@Slf4j
@Aspect
public class ErrorAdvice {
    @AfterThrowing(pointcut = "PointcutCommon.allPointcut()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
        //발생한 에러 확인로그 출력
        log.error("log: errorThrowing : {}\n\terror : {}\n\tStackTrace : {}", joinPoint.getSignature(), ex.getMessage(), ex.getStackTrace());
    }
}

 

 

Throwable과 Exception

  Throwable Exception
범위 Exception과 Error 체크 예외와 비체크 예외(런타임)
사용 예시 예상하지 못한 Error까지 로깅하고 싶을 때 (메모리 부족 등) 로직에서 발생할 수 있는 일반적인 예외만 처리하고자 할 때 (네트워크 오류, 데이터베이스 연결 실패 등)

 

즉, 모든 예외와 에러에 대해 로딩하고 싶다면 Thorwable을 사용하고 일반적인 예외에 대한 처리를 하고 싶다면 Exception을 사용하면 된다.