DispatcherServlet 에서 dispatcher란 "보내다, 급파하다" 라는 뜻을 가지고 있다. 디스패처 서블릿의 역할은 이처럼 Http 프로토콜 요청이 들어오는 가장 앞 단에서 컨트롤러에게 클라이언트의 요청을 전달하고, 컨트롤러가 리턴한 결과값을 View에 전달하여 알맞은 응답을 생성하도록 하는 Front Controller 이다. Spring Framework 의 유일한 프론트 컨트롤러인 DispatcherServlet 은 Spring MVC의 핵심 요소이다.
먼저 web.xml 쪽을 살펴보자.
<!-- 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>
'/' 모든 경로로 들어오는 요청을 'appServlet' 이라는 이름을 가진 서블릿을 통해 처리하도록 하였다.
다음은 Controller 이다.
@Controller 어노테이션을 설정해두었고, @RequestMapping에서 "/home"을 매핑하며 GET방식으로 받을 수 있도록 하였다.
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
그리고 임시로 프로젝트를 실행시켰을 때, 아래와 같은 로그를 확인 할 수 있다.
1. INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
2. INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Wed Aug 25 16:12:28 KST 2021]; root of context hierarchy
3. INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/root-context.xml]
4. INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2dd2ff87: defining beans []; root of factory hierarchy
5. INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 734 ms
6. 8월 25, 2021 4:12:28 오후 org.apache.catalina.core.ApplicationContext log
7. INFO: Initializing Spring FrameworkServlet 'appServlet'
8. INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'appServlet': initialization started
9. INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'appServlet-servlet': startup date [Wed Aug 25 16:12:28 KST 2021]; parent: Root WebApplicationContext
10. INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/appServlet/servlet-context.xml]
11. INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
12. INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
13. INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
14. INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5521407f: defining beans [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0,org.springframework.web.servlet.view.InternalResourceViewResolver#0,homeController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@2dd2ff87
15. INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/home],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.example.dante.HomeController.home(java.util.Locale,org.springframework.ui.Model)
16. INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
17. INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'appServlet': initialization completed in 1135 ms
이번에는 중요하다고 생각하는 포인트만 짚고 넘어가려 한다.
먼저 1번 줄에서 Root WebApplicationContext의 초기화가 시작되었다.
그리고 7,8번줄에서 아까 web.xml에서 설정한 'appServlet'이 초기화 되는 것을 알 수 있다.
10번줄에서 ServletContext를 통해 'servlet-context'에 있는 자원들을 불러오고 있다.
11,12 번 줄에서는 ClassPathBeanDefinitionScanner가 컴포넌트를 찾고 있는 것을 볼 수 있다. 이것은 @Component으로 등록된 것을 찾는 것이다. 사전 조건으로 나는 Controller로 사용하려는 클래스에 @Controller 어노테이션을 붙여놓았다. @Controller 는 @Component 어노테이션을 포함하고 있기때문에 스캐닝에 탐지 될 것이다.
15,16번 줄은 이전에 포스팅 했던 @RequestMapping를 참고한다면 쉽게 이해할 수 있을 것이다.
2021.08.19 - [Study/Spring] - [Spring] @RequestMapping
브라우져에서 설정한 URL을 입력하였을 때, 잘 동작 하는 것을 볼 수 있다.
지금까지 간단한 Spring MVC와 dispatcherServlet을 살펴보았다.
'Study > Spring' 카테고리의 다른 글
[Spring] Handler Method(ResponseEntity) (0) | 2021.09.12 |
---|---|
[Spring] @ModelAttribute (0) | 2021.09.08 |
[Spring] Spring IoC Container 그리고 Bean (0) | 2021.08.29 |
[Spring] @RequestMapping (0) | 2021.08.19 |
[Spring] Request Mapping - httpMethod (0) | 2021.08.15 |