본문으로 바로가기

직전에 진행했던 프로젝트에서는 예외 처리를 할 때 try-catch를 이용해서 했었다. 그러다보니 자연스럽게 코드 라인이 길어지고 가독성도 떨어졌었다. 또 복잡하게 보이는 코드 때문에 생산성이 떨어지는 느낌을 많이 받았고, 중복되는 부분이 너무 많았다!! 이 부분에 대해서 불만이 많았고 어떻게 하면 가독성을 좋게 만들 수 있을까? 라는 고민과 함께 @ControllerAdvice를 발견했다.

 

@ControllerAdvice 를 사용해서 예외 처리를 해보자!!


@ControllerAdvice?


@ExceptionHandler, @ModelAttribute, @InitBinder 가 적용된 메서드들에 AOP를 적용해 Controller 단에 적용하기 위해 고안된 어노테이션이라고 한다.
클래스에 선언하면 되며, 모든 @Controller에 대한, 전역적으로 발생할 수 있는 예외를 잡아서 처리할 수 있다.
@Component가 선언되어 있어 빈으로 관리되며 어쩌고저쩌고.. 설명이 기재되어 있는데, 잘 살펴보면 적용되는 우선순위에 대한 내용이 있는데..(공부하자)


@RestControllerAdvice?


@ControllerAdvice와 @ResponseBody를 합쳐놓은 어노테이션이다. @ControllerAdvice와 동일한 역할을 수행하고, 추가적으로 @ResponseBody를 통해 객체를 리턴할 수도 있다.

따라서 단순히 예외만 처리하고 싶다면 @ControllerAdvice를 적용하면 되고, 응답으로 객체를 리턴해야 한다면 @RestControllerAdvice를 적용하면 된다.

위 두 어노테이션 모두 적용 범위를 클래스나 패키지 단위로 제한할 수도 있으며, 아래와 같이 사용하면 된다.

 


@ExceptionHandler?

위에서 @ControllerAdvice에 대해서 이야기할 때 언급한 어노테이션이다. 이 어노테이션을 메서드에 선언하고 특정 예외 클래스를 지정해주면 해당 예외가 발생했을 때 메서드에 정의한 로직으로 처리할 수 있다. @ControllerAdvice 또는 @RestControllerAdvice에 정의된 메서드가 아닌 일반 컨트롤러 단에 존재하는 메서드에 선언할 경우, 해당 Controller에만 적용된다.

Controller, RestController에만 적용이 가능하다(@Service 등의 빈에서는 안된다..).


예제

가벼운 개념에 대해 알아봤다. 사용은 다음과 같이 하면 된다. 굉장히 간단하다.

@ControllerAdvice 또는 @RestControllerAdvice가 선언된 클래스 내부의 메서드에 위와 같이 어노테이션을 선언하고 처리할 예외 타입을 선언해주기만 하면 된다. 그러면 알아서 해당 예외를 exceptionHandler() 메서드에 정의된 로직으로 처리할 수 있게 된다. 여기서는 적용 범위를 지정해주지 않았으므로 전역적으로 예외를 처리하게 된다. Exception이 발생하면 해당 예외의 메시지를 콘솔에 출력할 것이다. 다음 사진과 같이 Controller에서 예외처리를 따로 하지 않아도 된다...!

이런식으로 사용하게 되면 예외 처리를 일괄적으로 모아서 관리해줄 수 있을 것이며 유지보수하기 용이해지지 않을까?

 

source https://velog.io/@banjjoknim/RestControllerAdvice