[Spring] DispatcherServlet이란?
0. 들어가기 전에
@RequestBody
의 동작을 알아보다가 DispatcherServlet, ~Resolver라는 언어가 많이 나와 이번 기회에 정리해보고 공부해봤습니다.
1. DispatcherServlet
중앙 Servlet으로써 요청 처리를 위한 공통의 알고리즘을 제공하는 클래스이다.
스프링 MVC는 프론트 컨트롤러 패턴으로 만들어졌다. 프론트 컨트롤러 패턴이란, 프론트 컨트롤러가 클라이언트의 요청을 받고 요청을 알맞게 처리해주는 컨트롤러들을 호출하여 처리하는 패턴이다.
[AS - IS]
위의 사진은 클라이언트가 요청을 하는 그림이다. 클라이언트가 서버에 요청을 할 때, 요청을 처리할 수 있는 컨트롤러를 직접 찾아서 매핑을 해주어야 한다.
[TO-BE]
하지만 프론트 컨트롤러를 도입하게 되면, 클라이언트는 프론트 컨트롤러로 요청하면, 프론트 컨트롤러가 처리할 수 있는 컨트롤러를 찾아서 정보를 전해준다.
위에 말한 프론트 컨트롤러가 스프링에선 DispatcherServlet이다. 이로써 스프링은 프론트 컨트롤러에서만 서블릿을 사용하고, 공통 로직들을 처리할 수 있게 되었다.
1.1 Servlet
자바에서 동적으로 웹 페이지를 처리하는 기술
그렇다면 Servletd이란 무엇일까? Servlet은 자바에서 동적으로 웹 페이지를 처리하는 기술로 자바 언어로 Http 관련 기능을 쉽게 이용하게 도와주는 클래스이다. HttpServletResponse
, HttpServletRequest
와 같은 클래스가 있으며 여러 편의 기능들이 있다.
2. MVC 동작과정
이제 Spring MVC를 이해해보자.
요청이 오면 DispatcherServlet
의 doDispatch
메서드가 실행된다.
1. 핸들러(컨트롤러) 매핑을 통해 핸들러 값을 찾는다.
// DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
mappedHandler = getHandler(processedRequest);
// ...
}
- DispatcherServlet의 getHandler 메서드가 HandlerExcutionChain을 가지고 온다.
- HandlerExcutionChain이 Handler(Controller)를 가지고 있다.
2. DispatcherServlet
의 getHandlerAdapter
가 mappedHandler
에서 handler
를 꺼내서 HandlerAdapter
를 가지고 온다.
// DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// ...
}
3. HandlerAdapter
의 handler
메서드를 실행한다.
- 이 때, mappedHandler가 파라미터로 같이 넘어간다.
4. 파라미터로 넘어간 mappedHandler
가 안에서 실행되어 컨트롤러를 가지고 온다.
5. 핸들러 어댑터가 핸들러를 실행시켜 ModelAndView
를 반환된다.
// DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ...
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// ...
}
6. 뷰 리졸버를 찾고 호출한다.
// DispatcherServlet#processDispatchResult
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
//...
if (mv != null && !mv.wasCleared()) {
render(mv, request, response); // 화면 렌더링
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
//...
}
7. 뷰 리졸버가 뷰의 논리이름을 물리 이름으로 바꾸고, 뷰 객체를 반환한다.
8. 뷰를 렌더링한다.
만약 @ResponseBody
나 @RestController
있으면 ModelAndView가 null이 되 뷰 리졸버가 호출되지 않고, HttpMessageConverter가 동작한다.
※ 참고
'FRAMEWORK > [SPRING]' 카테고리의 다른 글
[Spring] Spring Rest docs 적용해보기 (1) | 2023.05.21 |
---|---|
[Spring] HandlerMethodArgumentResolver 동작 원리 (0) | 2023.05.07 |
[Spring] Spring에서 Bean은 어떤 자료구조로 관리될까요? (0) | 2023.04.22 |
[Spring] Spring에서 DI하는 3가지 방법 (1) | 2023.04.21 |
[Spring] RestAssured로 API 테스트 진행하기 (1) | 2023.04.13 |