DispatcherServlet
: 요청 처리를 위한프론트 컨트롤러이다. 실제 작업은 적합한 컨트롤러에 의해 수행된다.: 서블릿 컨테이너의 가장 앞단에서 HTTP 프로토콜로 들어오는 모든 요청을 먼저 받아서
적합한 컨트롤러에 위임(Delegate request)해주는프론트 컨트롤러(Front Controller)이다.
DispatcherServlet은 모든 서블릿과 마찬가지로 서블릿Java configuration을 사용하여서블릿 사양을 따르거나web.xml에서 매핑되어야 한다.DispatcherServlet은Spring configuration을 사용하여 request mapping, view resolution, exception handling 등에 필요한 위임 구성 요소를 검색한다.

다음 Java configuration 예는 Servlet 컨테이너에 의해 자동 감지되는 DispatcherServlet을 등록하고 초기화한다
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
// Load Spring web application configuration
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
// Create and register the DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/app/*");
}
}
다음 web.xml configuration 예는 DispatcherServlet을 등록하고 초기화한다.
<web-app>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
Spring MVC는 DispatcherServlet이 등장함에 따라 web.xml의 역할을 상당히 축소시켜주었다. 과거에는 모든 서블릿을 URL 매핑을 위해 web.xml에 모두 등록해주어야 했지만, dispatcher-servlet이 해당 어플리케이션으로 들어오는 모든 요청을 핸들링해주고 공통 작업을 처리면서 상당히 편리하게 이용할 수 있게 되었다.
우리는 컨트롤러를 구현해두기만 하면 디스패처 서블릿이 알아서 적합한 컨트롤러로 위임을 해주는 구조가 되었다.
DispatcherServlet이 요청을 Controller로 넘겨주는 방식은 효율적으로 보인다. 하지만 DispatcherServlet이 모든 요청을 처리하다보니 이미지나 HTML/CSS/JavaScript 등과 같은 정적 파일에 대한 요청마저 모두 가로채는 까닭에 정적자원(Static Resources)을 불러오지 못하는 상황도 발생하곤 했다.
이러한 문제를 해결하기 위해 개발자들은 2가지 방법을 고안했다.
클라이언트의 요청을 2가지로 분리하여 구분한다.
/apps 의 URL로 접근하면 DispatcherServlet이 담당한다./resources 의 URL로 접근하면 DispatcherServlet이 컨트롤할 수 없으므로 담당하지 않는다.이러한 방식은 괜찮지만 상당히 코드가 지저분해지며, 모든 요청에 대해서 저런 URL을 붙여주어야 하므로 직관적인 설계가 될 수 없다. 그래서 이러한 방법의 한계를 느끼고 다음의 방법으로 처리를 하게 되었다.
두번째 방법은
DispatcherServlet이 요청을 처리할 컨트롤러를 먼저 찾고,요청에 대한 컨트롤러를 찾을 수 없는 경우에, 2차적으로 설정된 자원(Resource) 경로를 탐색하여 자원을 탐색하는 것이다. 이렇게 영역을 분리하면 효율적인 리소스 관리를 지원할 뿐 아니라 추후에 확장을 용이하게 해준다는 장점이 있다.

DispatcherServlet이 클라이언트의 모든 요청을 받는다.HandlerMappinng에 위임하여 처리할 Handler(Controller)을 찾는다.Handler을 수행할 수 있는 HandlerAdapter를 찾는다.HandlerAdapter가 요청을 컨트롤러로 위임한다. (DispatcherSevlet이 직접 요청을 컨트롤러에 위임하지 X)HandlerAdapter라는 어댑터 인터페이스를 통해 어댑터 패턴을 적용함으로써 컨트롤러의 구현 방식에 상관없이 요청을 위임할 수 있도록 하였다.HandlerAdapter는 Controller에 비즈니스 로직 처리를 호출한다.Controller는 비즈니스 로직을 수행하고, 처리 결과를 Model에 설정하며 HandlerAdapter에 view name을 반환한다.모델을 반환하면 View가 렌더링이 되고, 그렇지 않은 경우(ex. @RestController 등) View가 렌더링이 되지 않는다.view name을 ViewResolver에게 전달하고, ViewResolver은 해당하는 View 객체를 반환한다.DispatcherServlet은 View에게 Model을 전달하고 화면 표시를 요청한다.
DispatcherServrlet은 Spring MVC의 핵심 요소로 위 사진과 같은 계층 구조를 가지고 있다.
DispatcherServlet->FrameworkServlet->HttpServletBean->HttpServlet->GenericServlet->Servlet
Servlet[Servlet](https://velog.io/@dltnals1210/Spring-Web-%EC%84%9C%EB%B8%94%EB%A6%BFServlet#%EC%84%9C%EB%B8%94%EB%A6%BFservlet)은 웹 서버 내에서 실행되는 자바 프로그램이다.HTTP 통신을 사용하여 웹 클라이언트로부터 요청을 받고 응답하는 기술이다.일반적인 서블릿을 상속하는 GenericServlet, HTTP 서블릿을 상속하는 HttpServlet이 존재한다.init(), service(), destory()GenericServlet일반 서블릿이다.HTTP 서블릿을 작성하려면 HttpServlet을 상속받는다.HttpServletHTTP 서블릿 이다.HttpServlet의 하위 클래스는 아래 메서드 중 최소 하나의 메서드는 재정의해야한다.doGet(), doPost(), doPut(), doDelete()init(), destory(): 서블릿 라이프 사이클의 초기화 및 파기getServletInfo(): 서블릿에 대한 정보HttpServletBeanHttpServlet의 단순 확장 클래스로 Spring이 구현한 모든 서블릿 유형에 적합한 서블릿 (spring 패키지)FrameworkServlet스프링 웹 프레임워크의 기본 서블릿이다.doService() 메서드를 구현해야 한다.DispatcherServletHTTP 요청을 처리하는 중앙 집중형 Dispatcher (Front-Controller)어댑터 클래스를 통해 어떠한 workflow와도 사용이 가능할 만큼 매우 유연하다.Mapping, Adapter, Exception 관련 클래스는 다음과 같다.HandlerMapping - RequestMappingHandlerMappingHandlerAdapter - RequestMappingHandlerAdapterHandlerExceptionResolver - ExceptionHandlerExceptionResolver1.
HttpServlet: 서블릿의Request/Response를HttpServlet의Request/Response로 변환
2~5.FrameworkServlet: 클라이언트 요청의Http Method에 따라 분기 처리 -doXXX메서드
6.DispatcherServlet: 요청 정보에 대해 이를 처리할Handler를 찾고,HandlerAdapter를 통해Controller에 요청 위임
6-1. 요청에 매핑되는HandlerMapping(HandlerExecutionChain) 조회
6-2.Handler을 수행할 수 있는HandlerAdapter조회
6-3.HandlerAdapter를 통해 실제Controller의 비즈니스 로직 호출

Spring MVC의 핵심은 DispatcherServlet 이다.
DispatcherServlet에게 전달된다.DispatcherServlet 은 받은 요청을 분석한다. (Common Service)
HandlerMapping이 반환하는 HandlerExecutionChain객체
DispatcherServlet 은 HandlerMapping 에게 위임하여 요청을 처리할 Handler(Controller) 를 찾는다.HandlerMapping 은 요청 URL을 보고 Handler를 찾아서 Handler 의 이름과 함께 반환한다.HandlerExecutionChain타입이다. (handler과 인터셉터 관련 상태를 가지고 있다.)DispatcherServlet 은 찾아낸 Handler 를 실행할 수 있는 HandlerAdapter 를 찾는다.HandlerAdapter 를 사용해서 Handler 를 실행한다.Handler 를 실행하면서 비즈니스 로직 또한 실행한다.Handler의 리턴값 : View(뷰의 파일명), Model(비즈니스 로직 처리한 후의 데이터)DispatcherServlet 은 ViewResolver 에게 View 의 이름을 전달하고 View 객체를 얻는다.View Resolver 는 전략 객체이며 view name 뿐 아니라 헤더 정보(accept)도 전달된다.View Resolver 는 전달된 정보를 바탕으로 사용자에게 보여줄 View 가 무엇인지 결정한다.DispatcherServlet 은 View 객체에게 Model 과 함께 화면 표시를 의뢰한다.View 는 해당하는 뷰를(ex. JSP, Thymleaf..) 호출하며, Model 객체에서 화면 표시에 필요한 정보를 가져와 화면 표시를 처리한다.DispatcherServlet 은 View 로부터 받은 결과를 클라이언트에게 반환한다.
DispatcherServlet의doDispatch를 보면try-catch문을 볼 수 있다.즉, 요청중 발생하는 예외는
DispatcherServlet가catch를 해서 처리해준다.