DispatcherServlet
정리 안된 문서
@RestController
는 @Controller
의 class 의 모든 method 에 @ResponseBody
를 써준 것 뿐이다.
request
의 handler
를 먼저 찾고 handler adapter
를 그다음에 찾는다.
동작순서
요청분석 (로케일/테마/멀티파트 등)
핸들러 검색
기본으로 등록되는
BeanNameUrlHandlerMapping
RequestMappingHandlerMapping
핸들러 어뎁터 검색
핸들러 어뎁터를 사용해서 핸들러로 응답처리
핸들러의 리턴값을 보고 판단
뷰이름에 해당하는 뷰를 찾아서 모델 데이터를 렌더링
@ResponseEntity 가 있다면 Converter 를 사
(예외 발생시) 예외처리 핸들러
initStrategies()
DispatcherServlet
초기화 시 모든 전략을 설정하는 initStrategies()
org.springframework.web.servlet.DispatcherServlet extends FrameworkServlet
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
거슬러 올라가보면
org.springframework.web.servlet.FrameworkServlet extends HttpServletBean
@Override
protected final void initServletBean() {
...
createWebApplicationContext()
...
initWebApplicationContext()
...
}
//1.
protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {
...
configureAndRefreshWebApplicationContext()
...
}
protected void configureAndRefreshWebApplicationContext() {
...
ConfigurableWebApplicationContext.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));
}
private class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
FrameworkServlet.this.onApplicationEvent(event);
}
}
public void onApplicationEvent(ContextRefreshedEvent event) {
...
onRefresh();
...
}
//2.
protected WebApplicationContext initWebApplicationContext() {
....
onRefresh()
....
}
protected void onRefresh(ApplicationContext context) {
//empty
}
org.springframework.web.servlet.HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware
@Override
init() {
...
initServletBean();
}
protected void initServletBean() throws ServletException {
//empty
}
javax.servlet.http.HttpServlet extends GenericServlet implements Serializable
//nothing with that
javax.servlet.GenericServlet implements Servlet, ServletConfig, Serializable
init() {
//empty
}
구성요소
위에서 봤다시피 아래에 해당하는 구성요소를 초기화 한
protected void initStrategies(ApplicationContext context) {
/* 파일업로드 요청처리
javax.servlet.http Interface HttpServletRequest 를
org.springframework.web.multipart Interface MultipartHttpServletRequest 로 바꿔준다.
기본 DispatcherServlet 을 사용한다면 따로 등록하지 않는다.
SpringBoot 를 사용하면 기본적으로 하나를 등록해준다.
*/
initMultipartResolver(context);
/* 클라이언트의 로케일 확인
cookie, session, fixed, acceptheader 다양한 방식이 있음.
*/
initLocaleResolver(context);
/* 테마 처리
css, image 등 여러 리소스들을 테마로 관
cookie, session, fixed(default)
*/
initThemeResolver(context);
/* 핸들러 매핑
요청을 처리할 핸들러를 확인
기본으로 아래 두 핸들러매핑을 등
- RequestMappingHandlerMapping : 어노테이션 기반
- BeanNameUrlHandlerMapping : 빈의 이름을 기반
*/
initHandlerMappings(context);
/* 핸들러 어뎁터
요청을 처리할 핸들러의 어뎁터
*/
initHandlerAdapters(context);
/* 핸들러에서 뷰이름을 명시적으로 반환하지 않은 경우,
요청을 기반으로 뷰를 판하는 interface
*/
initHandlerExceptionResolvers(context);
/* 뷰 이름에 해당하는 뷰를 찾아내는 interface
*/
initRequestToViewNameTranslator(context);
/*
*/
initViewResolvers(context);
/*
post submit 후 화면 갱신으로 또 post submit 을 막는 패
post 요청 -> 처리 후 -> get redirect
이 상태에서 화면 refresh 를 해도 post 요청이 아닌 get 요청이 온다.
*/
initFlashMapManager(context);
}
Last updated
Was this helpful?