[Spring Boot] Dispatcher Servlet(디스패처 서블릿)의 개념과 동작 과정

메리·2023년 3월 15일
1

스프링 부트

목록 보기
2/5

0. 먼저 Servlet(서블릿)에 대해 알아보자.

서블릿이란 웹 서버의 성능을 향상하기 위해 사용되는 자바 클래스의 일종이다. 웹에 다양한 기능이 요구되면서 정적인 자료뿐만 아니라 동적인 페이지를 만들 필요가 생겼는데 이를 위해 만들어진 것이 바로 서블릿이다. 즉, 동적인 웹 페이지를 생성해 주는 자바 웹 프로그래밍 기술이라 할 수 있다. 이는 WAS(Web Application Server)의 서블릿 컨테이너 안에서 동작하게 된다. 요청(Request)을 받으면 요청에 맞는 로직을 실행하고 HTTP 형식으로 응답(Response) 하게 된다.

1. Dispatcher Servlet(디스패처 서블릿)이란?

디스패처 서블릿은 HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해 주는 Front Controller(프론트 컨트롤러)이다.

Front Controller(프론트 컨트롤러): 주로 서블릿 컨테이너의 제일 앞에서 서버로 들어오는 클라이언트의 모든 요청을 받아서 처리하는 컨트롤러

클라이언트로부터 요청이 들어오면 톰캣과 같은 서블릿 컨테이너가 요청을 받게 되고 이러한 모든 요청을 디스패처 서블릿이 가장 먼저 받는다. 디스패처 서블릿은 공통 작업을 먼저 처리한 후 해당 요청을 처리해야 하는 컨트롤러를 찾아 작업을 위임한다.
과거에는 URL 매핑을 위해 모든 서블릿을 web.xml에 등록해 주어야 했지만 디스패처 서블릿의 등장으로 web.xml의 역할을 상당히 축소해 줌과 동시에 편리하게 이용할 수 있게 되었다. 컨트롤러를 구현해두기만 하면 디스패처 서블릿이 알아서 적합한 컨트롤러로 위임을 해주는 구조이다.

2. Dispatcher Servlet(디스패처 서블릿)의 동작 과정

(1) 클라이언트의 요청을 Dispatcher Servlet에게 전달한다.
(2) 요청 정보를 통해 Handler Mapping이 요청을 위임할 컨트롤러를 찾는다.
(3) 요청을 컨트롤러로 위임할 Handler Adapter를 찾아서 전달한다.
(4) Handler Adapter가 컨트롤러로 요청을 위임한다.
(5) 비즈니스 로직을 처리한다.
(6) 컨트롤러가 요청을 처리한 후 반환값을 반환한다.
(7) Handler Adapter가 반환값을 처리한다.
(8) 서버의 응답을 클라이언트에게 전달한다.

(1) 클라이언트의 요청을 Dispatcher Servlet에게 전달한다.

디스패처 서블릿은 가장 먼저 요청을 받는 프론트 컨트롤러이다. 웹 컨텍스트에서 필터를 지나 스프링 컨텍스트에서 가장 먼저 요청을 받게 된다.

(2) 요청한 정보를 통해 Handler Mapping이 요청을 위임할 컨트롤러를 찾는다.

디스패처 서블릿은 요청 정보를 바탕으로 요청을 처리할 컨트롤러를 찾아야 한다. 주로 Handler Mapping의 구현체 중 하나인 RequestMappingHandlerMapping이 찾아준다.

(3) 요청을 컨트롤러로 위임할 Handler Adapter를 찾아서 전달한다.

디스패처 서블릿은 컨트롤러로 요청을 직접 위임하는 것이 아니라 Handler Adapter를 통해 컨트롤러로 요청을 위임한다.

(4) Handler Adater가 컨트롤러로 요청을 위임한다.

Handler Adapter가 컨트롤러로 요청을 넘기기 전에 공통적인 전처리 과정이 필요하다. 다양한 공통 작업이 수행되고 이러한 전처리 작업이 완료되면 파라미터 값과 함께 컨트롤러로 요청을 위임한다.

(5) 비즈니스 로직을 처리한다.

이후 컨트롤러는 서비스를 호출하고 비즈니스 로직이 진행된다.

(6) 컨트롤러가 요청을 처리한 후 반환값을 반환한다.

비즈니스 로직이 처리된 후 컨트롤러가 반환값을 반환한다. 응답 데이터를 사용하는 경우에는 주로 ResponseEntity를 반환하게 되고 응답 페이지를 보여주는 경우라면 String으로 View의 이름을 반환할 수 있다.

(7) Handler Adapter가 반환값을 처리한다.

컨트롤러로부터 받은 반환값을 응답 처리기인 ReturnValueHandler가 후처리한 후에 디스패처 서블릿으로 돌려준다. 만약 컨트롤러가 ResponseEntity를 반환하면 HttpEntityMethodProcessor가 MessageConverter를 사용해 응답 객체를 직렬화하고 응답 상태를 설정한다. 만약 컨트롤러가 View의 이름을 반환하면 View를 반환하기 위한 준비 작업을 처리한다.

(8) 서버의 응답을 클라이언트에게 전달한다.

디스패처 서블릿을 통해 반환되는 응답은 다시 필터를 거쳐 클라이언트에게 반환된다. 이때 응답이 데이터라면 그대로 반환되지만, 응답이 화면이라면 View의 이름에 맞는 View를 찾아서 반환해 주는 ViewResolver가 적절한 화면을 내려준다.


protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

  HttpServletRequest processedRequest = request;
  HandlerExecutionChain mappedHandler = null;
  ModelAndView mv = null;

// 1. 핸들러 조회
  mappedHandler = getHandler(processedRequest);
  
  if (mappedHandler == null) {
    noHandlerFound(processedRequest, response);
    
    return;
}

// 2. 핸들러 어댑터 조회 - 핸들러를 처리할 수 있는 어댑터
  HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 3. 핸들러 어댑터 실행 -> 4. 핸들러 어댑터를 통해 핸들러 실행 -> 5. ModelAndView 반환
  mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

}



private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {

// 뷰 렌더링 호출
  render(mv, request, response);
}


protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {

  View view;
  String viewName = mv.getViewName();

// 6. 뷰 리졸버를 통해서 뷰 찾기, 7. View 반환
  view = resolveViewName(viewName, mv.getModelInternal(), locale, request);

// 8. 뷰 렌더링
  view.render(mv.getModelInternal(), request, response);
}

출처:
[Web] 서블릿(Servlet)이란? 서블릿 컨테이너란?
[Spring] Dispatcher-Servlet(디스패처 서블릿)이란? 디스패처 서블릿의 개념과 동작 과정
실무에서 사용하는 Spring MVC 구조 & 순서 & 사용 완벽 정리

profile
하이루

0개의 댓글