ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 디스패처 서블릿(DispatcherServlet)의 개념과 동작흐름
    스프링 2022. 7. 5. 23:55

    The DispatcherServlet.

    프론트 컨트롤러.

    프론트 컨트롤러 패턴은 중앙집중형 컨트롤러를 모든 컨트롤러 제일 앞에 둬서 서버로 들어오는

    모든 요청을 먼저 받아서 처리하게 만듭니다.

     

    프론트 컨트롤러는 클라이언트가 보낸 요청을 받아서 공통적인 작업을 먼저 수행한 후에 적절한

    세부 컨트롤러로 작업을 위임해주고, 클라이언트에게 보낼 뷰를 선택해서 최종 결과를 생성하는 등의

    작업을 합니다.

    예외가 발생했을 때 이를 일관된 방식으로 처리하는 것도 프론트 컨트롤러의 역할입니다.

     

    디스패처 서블릿.

    스프링 서블릿/MVC의 중앙에 위치한 DispatcherServlet은 모든 연결을 담당하는 프론트 컨트롤러입니다.

     

    웹 브라우저로부터 요청이 들어오면 DispatcherServlet은 그 요청을 제일 앞단에서 받고 처리를 위해

    컨트롤러 객체를 검색합니다. 이때 DispatcherServlet은 직접 컨트롤러를 검색하지 않고

    HandlerMapping이라는 빈 객체에게 컨트롤러 검색을 요청합니다. HandlerMapping은 클라이언트의 요청 경로

    를 이용해서 이를 처리할 컨트롤러 빈 객체를 DispatcherServlet에게 전달합니다. 그 후 DispatcherServlet은

    HandlerAdapter 빈 객체에게 요청 처리를 위임합니다. HandlerAdapter가 알맞은 메서드를 호출해서 요청을 처리하고

    그 결과를 DispatcherServlet에게 전달합니다. 이때 HandlerAdapter는 처리 결과를 ModelAndView라는 객체로 변환해서

    DispatcherServlet에게 리턴합니다.

     

    DispatcherServlet는 다시 ViewResolver를 이용해서 View 객체를 찾고 View 객체에게 응답 결과 생성을 요청합니다.

     

     


     

    DispatcherServlet의 동작흐름

    MVC의 각 요소와 프론트 컨트롤러가 어떻게 협력해서 일하는지를 잘 파악해보도록 합시다.

     

    1. DispatcherServlet의 HTTP 요청 접수

    서블릿 컨테이너는 HTTP 프로토콜을 통해 들어오는 요청이 스프링의 DIspatcherServlet에 할당된 것이라면

    HTTP 요청정보를 DIspatcherServlet에 전달해줍니다. web.xml에는 보통 아래와 같이 전달받을 URL을 명시해둡니다.

     

    	<servlet-mapping>
    		<servlet-name>dispatcher</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>

    이 서블릿-맵핑은 모든 요청을 스프링의 프론트 컨트롤러인 DispatcherServlet에게 할당해주는 것입니다.

     

    DispatcherServlet은 모든 요청에 대해 공통적으로 진행해야 하는 전처리 작업이 등록된 것이 있다면

    이를 먼저 수행합니다. 공통적으로 이용 가능한 보안이나 파라미터 조작, 한글 디코딩과 같은 작업이 적용됩니다.

     

     

     

    2. DispatcherServlet가 HandlerMapping에게 검색 요청

    클라이언트의 요청을 실제로 처리하는 것은 컨트롤러이고 DispatcherServlet은 클라이언트의 요청을 전달받는 창구 역할을 합니다.

     

    DispatcherServlet은 URL이나 파라미터 정보, HTTP 명령 등을 참고로해서 어떤 컨트롤러에게 작업을 위임할지 결정합니다.  컨트롤러를 선정하는 것은 DispatcherServlet의 HandlerMapping을 이용합니다.

     

    HandlerMapping은 클라이언트의 요청 경로를 이용해서 이를 처리할 컨트롤러 빈 객체를 DispatcherServlet에 전달합니다.

    예를 들어 웹 요청 경로가 '/hell'라면 등록된 컨트롤러 빈 중에서 '/hello' 요청 경로를 처리할 컨트롤러를 리턴합니다.

     

    또한 어떤 HandlerMapping 전략을 선택할지는 DI를 통해 자유롭게 DispatcherServlet에 적용하여 결정할 수 있다.

     

     

     

    3. DispatcherServlet가 HandlerAdapter에게 역할 위임.

    어떤 컨트롤러/핸들러가 요청을 처리하게 할지를 결정했다면, 다음은 해당 컨트롤러의 메소드를 호출해서

    실제 웹 요청을 처리하는 작업입니다.

     

    HandlerAdapter가 필요한 이유:

    컨트롤러 객체를 DispatcherServlet이 전달받았다고 해서 바로 컨트롤러 객체의 메서드를 실행할 수 있는 것은

    아닙니다. DispatcherServlet은 @Controller 애노테이션을 이용해서 구현한 컨트롤러뿐만 아니라

    스프링 2.5까지 주로 사용했던 Conroller 인터페이스를 구현한 컨트롤러, 그리고 특수 목적으로 사용되는 

    HttpRequestHandler 인터페이스를 구현한 클래스를 동일한 방식으로 실행할 수 있도록 만들어졌습니다.

     

    @Controller 애노테이션, Conroller 인터페이스, HttpRequestHandler 인터페이스를 동일한 방식으로

    처리하기 위해 중간에 사용되는 것이 바로 HandlerAdapter입니다.

     

    전형적인 오브젝트 어댑터 패턴을 사용해서, 특정 컨트롤러를 호출해야 할 때는 해당 컨트롤러 타입을 지원하는

    어댑터를 중간에 껴서 호출하는 것입니다. 그러면 DispatcherServlet은 항상 일정한 방식으로

    컨트롤러를 호출하고 결과를 받을 수 있습니다.

     

    DIspatcherServlet은 핸들러 객체의 실제 타입에 상관없이 실행 결과를 ModelAndView라는 타입

    으로만 받을 수 있으면 됩니다. 하지만 ModelAndView 객체를 리턴하는 컨트롤러도 있고 그렇지 않은

    컨트롤러도 있습니다. 따라서 핸들러의 처리 결과를 ModelAndView로 변환해주는 객체가 필요하며

    HandlerAdapter가 이 변환을 처리해줍니다.

     

    DIspatcherServlet 핸들러 어댑터에 요청을 전달할 때는 모든 요청 정보가 담긴 HttpServletRequest 타입의

    오브젝트를 전달해줍니다. 이를 어댑터가 적절히 변환해서 컨트롤러의 메소드가 받을 수 있는 파라미터로 변환해서

    전달해주는 것입니다.

     

     

     

     

    4. 컨트롤러의 실행 결과를 보여줄 View 검색

    HandlerAdapter로부터 컨트롤러의 요청 처리 결과를 ModelAndView 객체로 받으면 

    DispatcherServlet은 결과를 보여줄 뷰를 찾기 위해 ViewResolver 빈 객체를 사용합니다.

    ModelAndView는 컨트롤러가 리턴한 뷰 이름을 담고 있는데 ViewResolver는 이 뷰 이름에 해당하는

    View 객체를 찾거나 생성해서 DispatcherServlet에 리턴합니다.

     

     

     

    5. View에게 응답 생성 요청

    DispatcherServlet는 ViewResolver가 리턴한 View 객체에게 응답 결과 생성을 요청합니다. JSP를 사용하는 경우

    View 객체는 JSP를 실행함으로써 웹 브라우저에 전송할 응답 결과를 생성하고 이로써 모든 과정이 끝이 납니다.

Designed by Tistory.