스프링 MVC 아키텍처를 살피면, "DispatcherSevlet" 이라는 용어가 매번 나온다. 내가 아는 범위에서는 dispatcher 라는 것은 준비상태에 있는 작업을 실행상태로 전환하는 역할을 하는 것으로 알고 있다. 하지만 스프링에서의 dispatcher는 ?
누군가가 DispatcherServlet 뭔데?
라고 묻는다면 나는 당연히 대답 못하겠지. 그래서 참고링크의 글을 따왔고 궁금증은 계속 수정해나가면서 해당 게시글을 개선해나갈 생각이다.
DispatcherServlet
Spring MVC Framework의 유일한 Front Controller인 DispatcherServlet은 Spring MVC의 핵심요소이다.
DispatcherServlet은 Controller로 향하는 모든 웹 요청의 진입점이며, 웹 요청을 처리하며, 결과 데이터를 Client에게 응답한다.
DispatcherServlet은 Spring MVC의 웹요청 Life Cycle을 주관한다고 할 수 있다.
스프링 MVC는 DispatcherSevlet 등장으로 web.xml의 역할이 축소되었다. 예전에는 서블릿 URL로 활용하기 위해 반드시 web.xml에 등록해주었지만, DispatcherServlet의 등장으로 해당 애플리케이션에 들어오는 요청을 모두 핸들링해줄 수 있기 때문이다.
그러나 여전히 web.xml의 중요성은 큰데 왜냐하면 servlet 으로 DispatcherServlet 을 등록해주어야 하며, 해당 객체의 URL 적용범위또한 web.xml에서 설정해주어야 하기 때문이다. 이후에 고급서비스를 위한 <filter> 혹은 <listener> 를 등록하는 역할 또한 web.xml의 기능으로 남아있다.
필터관련 처리를 생각하면 대표적인 UTF-8 인코딩 처리를 생각해보면 된다. JSP 페이지에서 한글 깨짐 문제 때문에 우리는 항상 web.xml에 해당 필터 내용을 추가하지 않는가.
web.xml에서 맡고 있는 <servlet> 매핑의 역할은 이제 DispatcherServlet으로 넘어갔다고 생각하자. web.xml에 DispatcherServlet의 <url-pattern> 을 " / " 로 설정함과 동시에 이제 모든 요청은 DispatcherServlet 의 영역이 되어버린 것이다.
물론 web.xml에 계속 서블릿을 매핑해줄수 있지만 이러한 방식을 버리고 DispatcherServlet을 이용해 웹개발을 좀 더 유용하며 간결할 것이라 생각한다.
아래는 실제 본인 프로젝트에 존재하는 web.xml의 내부 코드이다.
DispatcherServlet이 WebApplicationContext를 생성할 수 있도록 빈(Bean) 정보가 들어있는 파일들도 설정해주어야 한다.
빈 설정 파일을 하나 이상을 사용하거나, 파일 이름과 경로를 직접 지정해주고 싶은 경우에 contextConfigLocation 라는 초기화 파라미터 값에 빈 설정 파일 경로를 설정해준다.
아래의 내용을 설명하면 스프링프로젝트가 실행되면서 web.xml을 위에서 차례로 태그를 해석한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> | cs |
- DispatcherServlet 의 역할
DispatcherServlet을 이용한다는 것은 스프링에서 제공하는 @MVC를 이용하겠다는 말과 일맥상통한다. MVC(Model / View / Controller)의 설계영역을 완전히 분할하여 개발자가 MVC 패턴에 맞게끔 애플리케이션을 개발하도록 유도하는 방식이다.
내가 참고한 링크에서 DispatcherServlet를 아래와 같이 정의하고 있었다.
Model, Controller, View 의 각각의 영역을
조합하여 브라우저로 출력해주는 역할을 수행하는 클래스
[ 출처 : http://pds21.egloos.com/pds/201202/24/49/d0144949_4f47a0b19ed33.png ]
위의 처리과정의 대부분은 컨테이너가 대신 작업해주며, 개발자가 직접 구현해야할 부분은 많지 않다. 다만 위의 작업 흐름을 스스로 개발하면서 체감하고 있어야 한다. 클라이언트는 웹 클라이언트, 브라우저(IE, Chrome, Opera. Firefox ...) 등을 말한다.
작업흐름
(1) 클라이언트가 해당 애플리케이션에 접근하고, URL을 요청하면 해당 요청을 Dispatcher-Servlet이 중간에 가로챈다. 이렇게 가로채는 이유는 앞서서 web.xml에 DispatcherServlet의 <url-pattern> 이 " / " 와 같이 해당 애플리케이션의 모든 URL로 등록되었기 때문이다. 만약 특정 URL로 적용하고 싶다면 <url-pattern>의 내용을 바꿔주어 범위를 변경시키면 된다.
(2) 가로챈 정보를 HandlerMapping에게 보내 해당 요청을 처리할 수 있는 Controller를 찾는다.
(3) HandlerMapping이 해당 요청을 처리할 수 있는 Controller를 찾아낸다면 클라이언트의 요청을 해당하는 Controller에게 보내주게 된다. Controller는 개발자가 직접 구현해야 하는 부분이다.
(4) Controller는 해당 요청을 처리한 후 응답할 경우 View의 이름을 리턴하게 되는데, 리턴되는 view 이름을 ViewResolver가 먼저 받아 해당되는 View가 존재하는지 검색한다.
(5) 해당 View가 존재한다면, 처리결과를 View에 보낸 후, 처리 결과가 포함된 View를 다시 DispatcherServlet에게 보내주게 된다.
(6) DispatcherSevlet은 View로부터 받은 처리결과를 클라이언트에게 전송한다.
1 2 3 | <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> | cs |
'Spring' 카테고리의 다른 글
20180306 ContextLoaderListener & DispatcherServlet 이해 (0) | 2018.03.06 |
---|---|
20180301 @Autowired 에 대한 이해. (0) | 2018.03.01 |
20180205 <context:component-scan base-package="" /> (수정 : 2018 12 06) (0) | 2018.02.05 |
20180202 JSP : Between Different [ include & import ] (0) | 2018.02.02 |
20180125 스프링(Spring Framework) 특징 3 : POJO (0) | 2018.01.25 |