Search
Duplicate
🏢

Controller Advice

@ControllderAdvice란?

@ExceptionHandler, @InitBinder, @ModelAttribute와 같은 어노테이션은 @Controller 어노테이션이 적용된 클래스의 메소드에 사용시, 그들이 선언된 해당 Controller 클래스의 범위또는 상속 구조에만 적용된다.
@Controller 어노테이션 대신 @ControllerAdvice, @RestControllderAdvice 어노테이션이 적용된 클래스의 메소드에 사용하는 경우, 해당 메소드들은 모든 Controller 클래스에 적용된다.
더욱이 5.3버전에서부턴 @ControllderAdvice 클래스에 적용된 @ExceptionHandler 메소드는 다른 핸들러나 모든 @Controller 어노테이션이 적용된 클래스들로부터 발생한 예외를 처리하는데 사용될 수 있다.
@ControllerAdvice@Component 어노테이션이 메타 주석으로 포함되어 있으므로 컴포넌트 스캔을 통해 Bean으로 등록될 수 있다.
@RestControllerAdvice@ControllerAdvice@ResponseBody가 메타 주석으로 달려있으므로 이는 @ExceptionHandler 메소드가 뷰가 아닌 Body 값으로 반환 값을 렌더링함을 의미한다.
프로그램 시작 시 RequestMappingHandlerMappingExceptionHandlerExceptionResolver@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
복사
옵션들은 런타임 시 처리되며 이러한 옵션들이 전역적인 범위에서 사용될 경우 성능에 부정적인 영향을 미칠 수 있다.

어디에 쓸 수 있을까?

공통적으로 발생하는 예외들을 처리해주는 데 사용할 수 있을 것 같다.
즉 예외 처리의 책임을 컨트롤러가 아닌 핸들러에게 위임하여 컨트롤러가 본연의 목적인 표현과 요청 객체 처리에 조금 더 집중할 수 있을 것이다..!