스프링 MVC 핵심 구성 요소
스프링 MVC의 핵심 구성 요소는 DispatcherServlet을 중심으로 이루어져 있다고 볼 수 있다!
이전 포스팅에서 설명했지만 다시 한번 짚고 넘어가자면 DispatcherServlet은 Front-Controller 라고 보면 된다 모든 요청이 첫번째로 맞닥뜨리는 컨트롤러이다.
크게 9가지 순서로 나눠서 설명해보면
컨트롤러와 핸들러
스프링 MVC는 웹 요청을 처리할 수 있는 범용 프레임워크이다. 클라이언트 요청을 처리하는 객체의 타입이 @Controller일 수도, 자신이 직접 만든 클래스 일수도, HttpRequestHandler일 수도 있기 때문에 스프링 MVC는 웹 요청을 실제로 처리하는 객체를 Handler라고 표현한다.
따라서 특정 요청 경로를 처리해주는 핸들러를 찾아주는 객체를 HandlerMapping 이라고 부른다.
DispatcherServlet은 핸들러 객체의 실제 타입에 상관없이 실행결과를 ModelAndView라는 타입으로만 받을 수 있으면 된다. 하지만 핸들러의 실제 구현 타입에 따라 그렇지 않은 객체가 있는데 이 실행 결과를 ModelAndView로 변환해주는 객체가 HandlerAdapter이다.
DispatcherServlet과 스프링 컨테이너
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
config.MvcConfig
config.ControllerConfig
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
DispatcherServlet은 전달받은 설정파일을 이용해 스프링 컨테이너를 생성하는데, HandlerMapping,HandlerAdapter,Controller,ViewResolver 등의 빈은 DispatcherServlet이 생성한 스프링 컨테이너에서 구한다.
@Controller를 위한 HandlerMapping과 HandlerAdapter
// 스프링 MVC 설정을 활성화한다. 스프링 MVC를 사용하는데 필요한 다양한 설정을 생성한다.
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
이 설정은 매우 다양한 스프링 빈 설정을 추가해준다. 이 태그가 빈으로 추가해주는 클래스 중에는 @Controller 타입의 핸들러 객체를 처리하기 위한 다음의 두 클래스도 포함되어 있다.
직접 설정 예
package config;
// 스프링 MVC 프레임워크 동작 방식
// 직접 설정 예
import org.springframework.context.annotation.Bean;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import java.util.HashMap;
import java.util.Map;
// @Configuration
public class MvcConfigEx {
@Bean
public HandlerMapping handlerMapping() {
RequestMappingHandlerMapping hm = new RequestMappingHandlerMapping();
hm.setOrder(0);
return hm;
}
@Bean
public HandlerAdapter handlerAdapter() {
RequestMappingHandlerAdapter ha = new RequestMappingHandlerAdapter();
return ha;
}
@Bean
public HandlerMapping simpleHandlerMapping() {
SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();
Map<String, Object> pathMap = new HashMap<>();
pathMap.put("/**", defaultServletHandler());
hm.setUrlMap(pathMap);
return hm;
}
@Bean
public HttpRequestHandler defaultServletHandler() {
DefaultServletHttpRequestHandler handler = new DefaultServletHttpRequestHandler();
return handler;
}
@Bean
public HandlerAdapter requestHandlerAdapter() {
HttpRequestHandlerAdapter ha = new HttpRequestHandlerAdapter();
return ha;
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/view/");
vr.setSuffix(".jsp");
return vr;
}
}
@EnableWebMvc 어노테이션을 사용하지 않고 스프링 MVC를 사용하려면 설정파일을 이렇게 수정해주면 된다.
🖐 정리하자면,
DispatcherServlet은 웹 브라우저의 요청을 받기 위한 창구 역할을 하고, 다른 주요 구성 요소들을 이용해서 요청 흐름을 제어하는 역할을 한다.
HandlerMapping은 클라이언트의 요청을 처리할 핸들러 객체를 찾아준다. 핸들러(커맨드) 객체는 클라이언트의 요청을 실제로 처리한 뒤 뷰 정보와 모델을 설정한다.
HandlerAdapter는 DispatcherServlet과 핸들러 객체 사이의 변환을 알맞게 처리해준다.
ViewResolver는 요청 처리 결과를 생성할 View를 찾아주고
View는 최종적으로 클라이언트에 응답을 생성해서 전달한다.