[Spring] Spring Dispatcher Servlet (디스패처 서블릿)
Filter와 Interceptor
[Spring] Filter와 Interceptor
Filter? url 패턴이 맞는 요청에 대해 Dispatcher Servlet으로 요청되기 전, 후에 부가적인 작업을 한다. DIspatcher Servlet은 스프링의 가장 앞단에 존재하며, Filter는 스프링 컨테이너 밖, 톰캣 등의 웹 컨테
sm-jeon-develop.tistory.com
Dispatcher Servlet이란?
Http 프로토콜로 들어오는 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러이다.
과거에는 모든 서블릿을 URL 매핑을 위해 web.xml에 모두 등록해야 했다.
DispatcherServlet이 모든 요청을 핸들링하고, 공통 작업을 처리하게 되어, 컨트롤러를 구현하기만 하면 DispatcherServlet이 적합한 컨트롤러로 위임해주는 구조가 되었다.
스프링 구동 시 DispatcherServlet을 서블릿으로 등록하고, 모든 경로에 대해 매핑한다.
요청이 들어오면, Spring 내부에서 가장 먼저 DispatcherServlet이 요청을 받아들인다.
1. 요청 정보를 통해 요청을 위임할 컨트롤러를 찾는다. (getHandler)
2. 요청을 컨트롤러로 위임할 핸들러 어댑터를 찾아 전달한다. (getHandlerAdapter)
3. 인터셉터가 전처리를 한다.(applyPreHandle)
4. 핸들러 어댑터가 컨트롤러로 요청을 위임한다. (handle)
5. 컨트롤러에서 비즈니스 로직을 처리하고 응답을 반환한다.
6. 핸들러 어댑터가 반환값을 처리한다.
7. 인터셉터가 후처리를 한다. (applyPostHandle)
8. (컨트롤러 반환값이 ModelAndView라면) ViewResolver를 통해 View를 렌더링하고 Model을 사용하도록 넘겨준다.
9. 요청에 대한 작업이 모두 완료되었을때 인터셉터가 afterCompletion 메서드를 실행한다. (triggerAfterCompletion)
10. 서버 응답을 클라이언트로 반환한다.
ResponseBody를 사용하면, ViewResolver를 사용하지 않는다.
1. 요청 정보를 통해 요청을 위임할 컨트롤러를 찾는다.
어느 컨트롤러가 요청을 처리할 수 있는지를 식별하는 것이 HandlerMapping이다.
@Controller 방식은 RequestMappingHandlerMapping이 처리한다.
@Controller로 작성된 모든 컨트롤러를 찾아 파싱해 HashMap으로 관리한다.
요청이 오면 Http Method와 URI로 요청 정보를 만들고, HashMap에서 HandlerMethod를 찾아 HandlerExecutionChain으로 감싸 반환한다.
인터셉터 등을 포함하기 위해 HandlerExecutionChain로 감싼다.
2. 요청을 컨트롤러로 위임할 핸들러 어댑터를 찾아 전달한다.
DispatcherServlet은 컨트롤러로 요청을 직접 위임하지 않고, HandlerAdapter를 통해 위임한다.
컨트롤러의 구현 방식이 다양해, Adapter Interface를 통해 컨트롤러 구현 방식에 상관없이 요청을 위임한다.
3. 인터셉터가 전처리를 한다.
인터셉터의 preHandle 메서드를 실행하여, 컨트롤러가 실행되기 전, 전처리 과정을 거친다.
요청을 가공하거나, false를 반환하여 요청이 Controller에게 가지 않도록 할 수 있다.
4. 핸들러 어댑터가 컨트롤러로 요청을 위임한다.
인터셉터의 preHandle가 true를 반환했다면,
요청 시 @RequestParam, @RequestBody 등을 처리하기 위한 ArgumentResolver,
응답 시 ResponseEntity Body를 Json으로 직렬화하는 등 처리를 하는 ReturnValueHandler 등이 핸들러 어댑터에서 처리된다.
파라미터가 준비되면 컨트롤러로 요청을 위임한다.
5. 컨트롤러에서 비즈니스 로직을 처리하고 응답을 반환한다.
컨트롤러는 필요에 의해 서비스나 DB 등을 이용해 비즈니스 로직을 처리한 후, 응답을 가공하여 반환한다.
6. 핸들러 어댑터가 반환값을 처리한다.
4번에서의 설명처럼, ReturnValueHandler가 응답을 처리한다.
ResponseEntity라면 HttpEntityMethodProcessor가 MessageConverter를 사용해 HttpStatus를 설정하고, 응답 객체를 직렬화한다.
View 이름을 반환하면 8,9번 과정을 통해 화면을 렌더링한다.
7. 인터셉터가 후처리를 한다.
인터셉터의 postHandle 메서드를 실행하여, 컨트롤러가 응답을 반환한 후, 후처리 과정을 거친다.
응답을 가공하며, 컨트롤러 하위 계층에서 예외가 발생했다면, postHandle이 호출되지 않는다.
8. (컨트롤러 반환값이 ModelAndView라면) ViewResolver를 통해 View를 렌더링하고 Model을 사용하도록 넘겨준다.
컨트롤러가 ReponseEntity를 반환했다면, 해당되지 않는다.
반환한 view의 이름으로, ViewResolver를 통해 View를 반환한다.
9. 요청에 대한 작업이 모두 완료되었을때 인터셉터가 afterCompletion 메서드를 실행한다.
컨트롤러에서 예외가 발생했어도 실행된다.