이번 미션에서 학습하면서 사용했던 Interceptor, ArgumentResolver에 대해서 다시 정리해보려고 한다.
인증 등을 인터셉터로 구현하면, 컨트롤러의 책임이 줄어들고 중복 코드를 제거할 수 있다.
Handler의 실행을 가로챈다.
HandlerInterceptor
인터페이스를 구현해서 만들 수 있다.
preHandle
: 조건에 따라 true를 반환하면 Handler를 실행한다.
postHandle
: 컨트롤러가 실행되고 동작한다.
afterCompletion
: View에 전달되고 동작한다.
컨트롤러에 들어온 요청으로부터 원하는 객체를 만들어낼 수 있다.
HandlerMethodArgumentResolver
인터페이스를 구현해서 만들 수 있다.
supportsParameter
: 조건에 따라 true를 반환하면 resolveArgument()를 호출한다.
resolveArgument
: 원하는 객체를 만들어서 리턴한다.
Spring MVC의 동작은 아래와 같다.
@Autowired
를 사용해서 아래와 같이 인터페이스에 의존해서 생성자 주입받고 있다.
하지만 스프링에는 기본적으로 위의 인터페이스들을 구현한 구현체가 있는 것으로 알고 있다.
이때 생성자 주입을 추상 타입으로 받는다면 내가 커스텀한 인터셉터 말고도 해당 타입의 빈이 존재하지 않을까??
원하는 대로 주입 받을 수 있을 지 궁금했다.
스프링 부트에는 WebMvcAutoConfiguration
이라는 기본 Configuration이 존재한다.
이것은 위의 @Conditional에 따라서 빈으로 등록이 되고 동작한다.
예를 들어 WebMvcConfigurationSupport
가 존재하지 않는다면 이 설정이 적용된다. (이 조건이 궁금하다면 @EnableWebMvc를 보면 알 수 있다)
이 안에는 위와 같은 빈이 등록되는데, 이때 기본 인터셉터들을 세팅하는 것을 볼 수 있다.
mvcConversionService
와 mvcResourceUrlProvider
을 사용해서 인터셉터를 만드는 메서드 getInterceptors()
가 동작한다.
해당 메서드를 들어가보자.
두가지의 인터셉터를 만들어서 등록하고 있는 모습이다.
각각의 클래스를 들어가보면 HttpServletRequest
의 저장공간에 전달 받은 파라미터를 저장해서 다른 곳에서 사용할 수 있도록 하는 역할을 한다.
중요한 것은 이 두 인터셉터 객체는 new 키워드를 통해서 생성한다는 점이다!!
결론은 스프링 빈으로 관리되지 않기 때문에 HandlerInterceptor
타입의 스프링 빈에는 존재하지 않는다.
따라서 BasicAuthInterceptor implements HandlerInterceptor
등으로 만든 유일한 빈이 의존 타입으로 주입될 수 있다.
틀린 내용이 있다면 지적 부탁드려요!!