직전에 진행했던 프로젝트에서는 예외 처리를 할 때 try-catch
를 이용해서 했었다. 그러다보니 자연스럽게 코드 라인이 길어지고 가독성도 떨어졌었다. 또 복잡하게 보이는 코드 때문에 생산성이 떨어지는 느낌을 많이 받았고, 중복되는 부분이 너무 많았다!! 이 부분에 대해서 불만이 많았고 어떻게 하면 가독성을 좋게 만들 수 있을까? 라는 고민과 함께 @ControllerAdvice
를 발견했다.
@ControllerAdvice 를 사용해서 예외 처리를 해보자!!
@ExceptionHandler
, @ModelAttribute
, @InitBinder
가 적용된 메서드들에 AOP
를 적용해 Controller
단에 적용하기 위해 고안된 어노테이션이라고 한다.
클래스에 선언하면 되며, 모든 @Controller
에 대한, 전역적으로 발생할 수 있는 예외를 잡아서 처리할 수 있다.
@Component
가 선언되어 있어 빈으로 관리되며 어쩌고저쩌고.. 설명이 기재되어 있는데, 잘 살펴보면 적용되는 우선순위에 대한 내용이 있는데..(공부하자)
@ControllerAdvice
와 @ResponseBody
를 합쳐놓은 어노테이션이다. @ControllerAdvice
와 동일한 역할을 수행하고, 추가적으로 @ResponseBody
를 통해 객체를 리턴할 수도 있다.
따라서 단순히 예외만 처리하고 싶다면 @ControllerAdvice
를 적용하면 되고, 응답으로 객체를 리턴해야 한다면 @RestControllerAdvice
를 적용하면 된다.
위 두 어노테이션 모두 적용 범위를 클래스나 패키지 단위로 제한할 수도 있으며, 아래와 같이 사용하면 된다.
위에서 @ControllerAdvice
에 대해서 이야기할 때 언급한 어노테이션이다. 이 어노테이션을 메서드에 선언하고 특정 예외 클래스를 지정해주면 해당 예외가 발생했을 때 메서드에 정의한 로직으로 처리할 수 있다. @ControllerAdvice
또는 @RestControllerAdvice
에 정의된 메서드가 아닌 일반 컨트롤러 단에 존재하는 메서드에 선언할 경우, 해당 Controller
에만 적용된다.
Controller, RestController에만 적용이 가능하다(@Service 등의 빈에서는 안된다..).
가벼운 개념에 대해 알아봤다. 사용은 다음과 같이 하면 된다. 굉장히 간단하다.
@ControllerAdvice
또는 @RestControllerAdvice
가 선언된 클래스 내부의 메서드에 위와 같이 어노테이션을 선언하고 처리할 예외 타입을 선언해주기만 하면 된다. 그러면 알아서 해당 예외를 exceptionHandler()
메서드에 정의된 로직으로 처리할 수 있게 된다. 여기서는 적용 범위를 지정해주지 않았으므로 전역적으로 예외를 처리하게 된다. Exception
이 발생하면 해당 예외의 메시지를 콘솔에 출력할 것이다. 다음 사진과 같이 Controller
에서 예외처리를 따로 하지 않아도 된다...!
이런식으로 사용하게 되면 예외 처리를 일괄적으로 모아서 관리해줄 수 있을 것이며 유지보수하기 용이해지지 않을까?