디스패처 서블릿이란?
HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러(Front Controller)
서블릿(자바 서블릿)
- 자바를 사용하여 웹 페이지를 동적으로 생성하는 서버측 프로그램
- 클라이언트의 요청을 처리하고, 그 결과를 반환하는 웹 프로그래밍 기술
클라이언트로부터 어떠한 요청이 오면 Tomcat(톰캣)과 같은 서블릿 컨테이너가 요청을 받는다. 이 모든 요청을 프론트 컨트롤러인 디스패처 서블릿이 가장 먼저 받게 된다. 그러면 디스패처 서블릿은 공통적인 작업을 먼저 처리한 후에 해당 요청을 처리해야하는 컨트롤러를 찾아서 작업을 위임한다.
- 스프링 부트에서는 스프링 부트 구동시 DispatcherServlet을 서블릿으로 자동 등록하고, 모든 경로 "/"에 대해 매핑
Front Controller : 서블릿 컨테이너의 제일 앞에서 서버로 들어오는 클라이언트의 모든 요청을 받아서 처리해주는 컨트롤러, MVC 구조와 함께 사용되는 디자인 패턴
장점
- 과거에는 모든 서블릿을 URL 매핑을 위해 web.xml 에 모두 등록해줘야했지만, dispatcher-servlet이 해당 어플리케이션으로 들어오는 모든 요청을 핸들링해주고 공통 작업을 처리면서 상당히 편리하게 이용가능해졌다
-> 컨트롤러만 구현해두면, 디스패처 서블릿가 알아서 적합한 컨트롤러로 위임해주는 구조
정적 자원의 처리
- Dispatcher Servlet 이 모든 요청을 처리하다보니, 정적파일 ( 이미지,HTML/CSS/JavaScript) 에 대한 요청도 모두 가로채어 정적자원을 불러오지 못하는 상황 발생
이에 대한 해결 방안 2가지
1. 정작 자원 요청과 애플리케이션 요청을 분리
- 클라이언트의 요청을 2가지로 분리하는 것
- /apps 의 URL 로 접근하면 Dispatcher Servlet 이 담당
- /resources 의 URL 로 접근하면 Dispatcher Servlet 이 담당x
- 코드가 지저분해지며, 모든 요청에 대해 URL 을 붙여줘야함
- 애플리케이션 요청을 탐색하고 없으면 정적 자원 요청으로 처리
- Dispatcher Servlet이 요청을 처리할 컨트롤러를 먼저 찾고, 요청에 대한 컨트롤러를 찾을 수 없는 경우엔, 2차적으로 설정된 자원 경로를 탐색하여 자원을 탐색
- 영역을 분리해 효율적인 리소스 관리 지원, 추후에 확장에 용이
Dispatcher-Servlet 의 동작 과정

1. 클라이언트의 요청을 디스패처 서블릿이 받음
- 디스패처 서블릿은 가장 먼저 요청을 받는 프론트 컨트롤러이다.
- 서블릿 컨테이너 (웹 컨텍스트) 에서 필터를 지나 스프링 컨텍스트에서 디스패처 서블릿이 가장 먼저 요청을 받게된다.
2. 요청 정보를 통해 요청을 위임할 컨트롤러를 찾음
-
디스패처 서블릿은 요청을 처리할 핸들러(컨트롤러)를 찾고 해당 객체의 메소드를 호출한다
-
가장 먼저 어느 컨트롤러가 요청을 처리할 수 있는지를 식별해는 역할-HandlerMapping
-
컨트롤러 구현하는 방법이 다양하기 때문에, 스프링은 HandlerMapping 인터페이스를 만들어놓고, 다양한 구현 방법에 따라 요청을 처리할 대상을 찾도록 되어있다
-
@Controller 방식은 RequestMappingHandlerMapping 이 처리
- @Controller 로 작성된 모든 컨트롤러를 찾고 파싱하여 HashMap으로 <요청 정보,처리할 대상> 관리한다
- 처리할 대상은 HandlerMethod 객체로 컨트롤러, 메서드 등을 갖고 있는데 이는 스프링이 리플렉션을 이용해 요청을 위임하기 때문
-
요청이 오면 (Http Method, URI) 등을 통해 요청 정보를 만들고, HashMap 에서 요청을 처리할 대상을 찾은 후 HandlerExecutionChain으로 감싸서 반환
- 감싸는 이유는 컨트롤러로 요청을 넘겨주기 전에 처리해야하는 인터셉터 등을 포함하기 위해서
3. 요청을 컨트롤러로 위임할 핸들러 어댑터를 찾아서 전달함
- 컨트롤러로 요청을 위임해야 하는데, 디스패처 서블릿은 컨트롤러로 요청을 직접 위임하는 것이 아니라 HandlerAdapter를 통해 위임
- 다양하게 작성되는 컨트롤러에 대응하기 위해 HandlerAdapter 라는 어댑터 인터페이스를 통해 어댑터 패턴을 적용함으로써 컨트롤러의 구현 방식에 상관없이 요청을 위임할 수 있도록 하였다
4.핸들러 어댑터가 컨트롤러로 요청을 위임함
-
핸들러 어댑터가 컨트롤러로 요청을 위임하기 전/후에 공통적인 전/후처리 과정 필요
1) ArgumentResolver : 인터셉트들을 포함해 요청시에 @RequestParam, @RequestBody 등을 처리
2) ReturnValueHandler: 응답시에 ResponseEntity의 Body 를 Json 으로 직렬화하는 등의 처리
-
ArgumentResolver등을 통해 파라미터가 준비 되면 리플렉션을 이용해 컨트롤러로 요청을 위임
5.비즈니스 로직 처리
- 컨트롤러는 서비스를 호출하고, 작성한 비즈니스 로직들이 진행
6.컨트롤러가 반환값을 반환
- 비즈니스 로직이 처리된 후에 컨트롤러가 반환값 반환
- 최근에는 주로 응답 데이터를 사용하는 ResponseEntity를 사용해 반환
7.핸들러 어댑터가 반환값을 처리함
- Handler Adapter 는 컨트롤러로부터 받은 응답을, 응답 처리기인 ReturnValueHandler 가 후처리한 후에 디서패처 서블릿으로 돌려준다
- 컨트롤러가 ResponseEntity 를 반환하면 HttpEntityMethodProcessor 가 MessageConverter를 사용해 응답 객체를 직렬화하고 응답 상태를 설정
- 컨트롤러가 View 이름을 반환하면 ViewResolver 를 통해 View를 반환
8.서버의 응답을 클라이언트로 반환
- 디스패처 서블릿을 통해 반환되는 응답은 다시 필터들을 거쳐 클라이언트에게 반환
- 응답이 화면이라면 View 의 이름에 맞는 View를 찾아서 반환해주는 ViewResolver가 적절한 화면을 내린다
정리

- 처음 클라이언트에서 요청이 오면 디스패처 서블릿이 해당 요청을 받는다.
- Handler Mapping을 통해 요청에 알맞은 컨트롤러를 찾아낸다.
- 찾아낸 컨트롤러를 Handler Adapter를 통해 해당 컨트롤러의 메서드를 실행시킨다.
- 컨트롤러는 요청을 처리한 뒤 처리한 결과와 해당 뷰 정보(ModelAndView)를 다시 디스패처 서블릿에게 전달한다.
- 받은 정보로 디스패처 서블릿은 View Resolver를 통해 View 파일을 찾는다.
참고