@ControllderAdvice란?
•
@ExceptionHandler, @InitBinder, @ModelAttribute와 같은 어노테이션은 @Controller 어노테이션이 적용된 클래스의 메소드에 사용시, 그들이 선언된 해당 Controller 클래스의 범위또는 상속 구조에만 적용된다.
•
@Controller 어노테이션 대신 @ControllerAdvice, @RestControllderAdvice 어노테이션이 적용된 클래스의 메소드에 사용하는 경우, 해당 메소드들은 모든 Controller 클래스에 적용된다.
◦
더욱이 5.3버전에서부턴 @ControllderAdvice 클래스에 적용된 @ExceptionHandler 메소드는 다른 핸들러나 모든 @Controller 어노테이션이 적용된 클래스들로부터 발생한 예외를 처리하는데 사용될 수 있다.
•
@ControllerAdvice는 @Component 어노테이션이 메타 주석으로 포함되어 있으므로 컴포넌트 스캔을 통해 Bean으로 등록될 수 있다.
◦
@RestControllerAdvice는 @ControllerAdvice와 @ResponseBody가 메타 주석으로 달려있으므로 이는 @ExceptionHandler 메소드가 뷰가 아닌 Body 값으로 반환 값을 렌더링함을 의미한다.
•
프로그램 시작 시 RequestMappingHandlerMapping과 ExceptionHandlerExceptionResolver는 @ControllerAdvice가 적용된 Bean들을 찾아 런타임 시 적용시킨다.
◦
@ControllerAdvice가 붙은 클래스로부터 생성된 @ExceptionHandler 메소드는 전역에 지역 메소드는 @Controller에 각각 적용된다. 반면 전역 @ModelAttribute 및 @InitBinder 메소드는 지역 메소드보다 우선된다.
▪
전역 범위보다 지역 범위가 먼저다.
•
@ControllerAdvice에 옵션을 추가하면 적용되는 Controller 집합의 범위를 좁힐 수 있다.
// Target all Controllers annotated with @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// Target all Controllers within specific packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Target all Controllers assignable to specific classes
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
Java
복사
◦
옵션들은 런타임 시 처리되며 이러한 옵션들이 전역적인 범위에서 사용될 경우 성능에 부정적인 영향을 미칠 수 있다.
어디에 쓸 수 있을까?
•
공통적으로 발생하는 예외들을 처리해주는 데 사용할 수 있을 것 같다.
•
즉 예외 처리의 책임을 컨트롤러가 아닌 핸들러에게 위임하여 컨트롤러가 본연의 목적인 표현과 요청 객체 처리에 조금 더 집중할 수 있을 것이다..!