Spring에서의 요청 흐름 4 - Interceptor

Updated: Categories:

요청을 가로채는 녀석인 Interceptor에 대해 알아보자

Interceptor

앞선 포스팅에서 DispatcherServlet이 어떻게 동작하는지를 살펴보았다.
DispatcherServlet이 매핑되는 컨트롤러를 스프링 컨테이너에서 찾아낸 다음 실행시켰는데, 이 과정에서 사실 Interceptor라는 녀석이 먼저 동작한다.

그럼 Interceptor의 정의에 대해 먼저 살펴보면,

Controller의 Handler를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 일종의 필터

엥? Controller의 Handler가 뭐지..? 분명 서블릿 컨테이너에 시작점에도 서블릿 필터가 있었는데, 이 필터랑은 다른것일까?
그럼 두 기능의 차이점은 뭘까?

차이점

우선 두 객체가 존재하는 위치가 아예 다르다.

filter는 Servlet Container에서 존재하고, interceptor는 Spring Container에 존재한다.
(따라서 filter는 J2EE 표준 스펙에 정의된 기능이고, interceptor는 Spring 프레임워크의 기능이다)

이를 그림으로 나타내면 다음과 같다

사실 필터와 인터셉터의 근본적인 역할은 동일하다. 요청이 처음 들어왔을 때, 요청에 대한 공통적인 처리를 담당하는 것이다.
다만 위치와 적용 시점이 다르기 때문에 정확히 어떤 역할을 하는지가 중요하다!

image

위 그림과 같이 필터는 ServletRequest 객체를 받고, 인터셉터는 HttpServletRequest 객체를 받는다.
(HttpServletRequestServletRequest를 상속받는다)

따라서 필터는 모든 http에 대한 전역적인 처리가 가능하기에 인코딩 변환, 파일 압축, 보안 적용 등 Spring과 무관한 작업에 사용된다.
즉 비즈니스 로직과 상관없이 http 구조를 뜯어보는것(?) 자체에 집중되어 있는 느낌인 것이다.

반면 인터셉터는 완성된 HttpServletRequest 객체를 받기에, http의 데이터를 변경시킨다기보다는 ‘사용’하는 느낌이다.
또한 인터셉터를 여러개 만들어 컨트롤러를 선택하여 적용시킬 수도 있다.
따라서 인터셉터로그인 및 권한 체크, 로그처리, 실행시간 계산 등 비즈니스 로직 시작 전 수행해야 하는일에 주로 사용된다.


동작 원리

이제 인터셉터가 어떤 역할을 하는지 알았으니 실제로 어떻게 동작하는지 알아보자.
우선 기본적으로 인터셉터는 DispatcherServlet과 Controller 사이에 위치하고, ApplicationContext에 등록되어 있다.

이전 포스팅에서의 DispatcherServlet 동작원리 그림을 다시 살펴보면,

위 그림의 4번 과정을 살펴보면, HandlerAdapterHandler(컨트롤러 메소드)를 실행시킨다.
이 때 Handler의 실행 전 후로 인터셉터가 동작한다!

  • 실행 전 : preHandle에 기능을 정의
  • 실행 후 : postHandle에 기능을 정의

이를 저 부분만 똑 떼어서 다시 그림으로 나타내보면 아래와 같다.

이렇게 실제 요청이 최종적으로 도달하기 전 공통된 기능을 정의해줄 수 있다.


정리

인터셉터는 필터와 가장 많이 비교되는 기능이다.
필터와 매우 유사한 것 같지만, 꽤나 많은 차이점이 있으니 이를 명확히 알고 적절하게 사용해야 한다.
이번 포스팅에서는 인터셉터가 무엇인지만 알아보았는데, 실제 구현은 마지막 포스팅에서 해보도록 하겠다.

요청이 여기까지 도달했으면 이제 드디어 서비스 로직이 실행되는건가 싶지만, 슬프게도 비즈니스 로직에서 적용되는 한가지 기술이 더 남아있다…
다음 포스팅에서는 마지막 동작, AOP에 대해 알아보도록 하겠다.