SpringMVC源码解析系列2-DispatcherServlet

1,454 阅读3分钟

DispatcherServlet初始化过程

DispathcerServlet继承关系

可以看到有几个生命周期接口:

  1. ApplicationContextAware:保存了spring上下文

    public interface ApplicationContextAware extends Aware {
    	//上下文初始化完成后被调用
    	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
    }
    #org.springframework.web.servlet.FrameworkServlet	
    //保存SpringMVC上下文 当通过Spring装载DispatchServlet时会被调用
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
    	if (this.webApplicationContext == null && applicationContext instanceof WebApplicationContext) {
    		this.webApplicationContext = (WebApplicationContext) applicationContext;
    		this.webApplicationContextInjected = true;
    	}
    }
    
    
  2. EnvironmentAware:保存了环境变量对象

    public interface EnvironmentAware extends Aware {
    	//环境变量对象初始化完成后被调用
    	void setEnvironment(Environment environment);
    }
    #org.springframework.web.servlet.HttpServletBean
    	@Override
    	public void setEnvironment(Environment environment) {
    		Assert.isInstanceOf(ConfigurableEnvironment.class, environment, "ConfigurableEnvironment required");
    		this.environment = (ConfigurableEnvironment) environment;
    	}
    
  3. Servlet:Servlet生命周期

    public interface Servlet {
       //serlvet初始化
        public void init(ServletConfig config) throws ServletException;
        public ServletConfig getServletConfig();
        public void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException;
        public String getServletInfo();
      //serlvet销毁
        public void destroy();
    }
    #org.springframework.web.servlet.HttpServletBean
    @Override
    public final void init() throws ServletException {
    	...
    	initServletBean();
    }
    @Override
    public void destroy() {
    	if (this.webApplicationContext instanceof ConfigurableApplicationContext && !this.webApplicationContextInjected) {
    		//销毁上下文
    		((ConfigurableApplicationContext) this.webApplicationContext).close();
    	}
    }
    #org.springframework.web.servlet.FrameworkServlet
    DispatcherServlet extends FrameworkServlet 
    #org.springframework.web.servlet.FrameworkServlet
    @Override
    protected final void initServletBean() throws ServletException {
    	...
    	try {
    		this.webApplicationContext = initWebApplicationContext();
    		initFrameworkServlet();
    	}
    	...
    }
    protected WebApplicationContext initWebApplicationContext() {
    	WebApplicationContext rootContext =
    			WebApplicationContextUtils.getWebApplicationContext(getServletContext());
    	WebApplicationContext wac = null;
    	...
    	//以spring配置方式时webApplicationContext!=null
    	if (this.webApplicationContext != null) {
    			wac = this.webApplicationContext;
    			if (wac instanceof ConfigurableWebApplicationContext) {
    				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
    						cwac.setParent(rootContext);
    				}
    			}
    		}
    	if (wac == null) {
    		//创建applicationContext
    		wac = createWebApplicationContext(rootContext);
    	}
    	...
    	return wac;
    }
    protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {
    	//XmlWebApplicationContext 
    	Class<?> contextClass = getContextClass();
    	...
    	//创建applicationContext
    	ConfigurableWebApplicationContext wac =
    			(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
    	wac.setEnvironment(getEnvironment());
    	//设置parent(ContextLoadListener中创建的applicationContext)
    	wac.setParent(parent);
    	//读取contextConfigLocation配置
    	wac.setConfigLocation(getContextConfigLocation());
    	//refresh()
    	configureAndRefreshWebApplicationContext(wac);
    	return wac;
    }
    //当SpringMVC上下初始化完成后会去装载默认策略(HandlerMapping,HandleAdapter)
    protected void initStrategies(ApplicationContext context) {
      //获取容器中是否有其实现 没有则加载DispatcherServlet.properties中的默认实现
    	initMultipartResolver(context);
    	initLocaleResolver(context);
    	initThemeResolver(context);
    	initHandlerMappings(context);
    	initHandlerAdapters(context);
    	initHandlerExceptionResolvers(context);
    	initRequestToViewNameTranslator(context);
    	initViewResolvers(context);
    	initFlashMapManager(context);
    }
    
    org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
    org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
    org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
    	org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
    org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
    	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
    	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
    org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
    	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
    	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
    org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
    org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
    org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
    

DispatcherServlet调用过程

@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
	//将相关配置设置到request作用于中
	request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
	request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
	request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
	request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
  	...
	request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
	request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

	try {
		doDispatch(request, response);
	}
}

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
	...
	try {
		ModelAndView mv = null;
		Exception dispatchException = null;
		try {
			processedRequest = checkMultipart(request);
			multipartRequestParsed = (processedRequest != request);
			//1.调用handlerMapping获取handlerChain
			mappedHandler = getHandler(processedRequest);
			if (mappedHandler == null || mappedHandler.getHandler() == null) {
				noHandlerFound(processedRequest, response);
				return;
			}
			// 2.获取支持该handler解析的HandlerAdapter
			HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
          	//前置处理(CORS时用到)
			if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}
			// 3.使用HandlerAdapter完成handler处理
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
			//如果是异步请求 直接返回 
			if (asyncManager.isConcurrentHandlingStarted()) {
				return;
			}
			applyDefaultViewName(request, mv);
          	//后置处理
			mappedHandler.applyPostHandle(processedRequest, response, mv);
		}
		catch (Exception ex) {
			dispatchException = ex;
		}
      	//4.异常处理,视图解析,渲染返回
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
	}
	...
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
		HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
	boolean errorView = false;
  	//如果HandlerAdapter.handler()执行异常 则进行异常处理
	if (exception != null) {
		...
          Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
      //4.1
        mv = processHandlerException(request, response, handler, exception);
        errorView = (mv != null);
	}


	if (mv != null && !mv.wasCleared()) {
      	//4.2 视图解析 渲染返回
		render(mv, request, response);
		if (errorView) {
			WebUtils.clearErrorRequestAttributes(request);
		}
	}
}
//异常处理
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
		Object handler, Exception ex) throws Exception {
	ModelAndView exMv = null;
	for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
      	//使用异常解析器解析异常(类似HandlerAdapter参数解析,调用)
		exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);
		if (exMv != null) {
			break;
		}
    }
  	...
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
	//国际化
	Locale locale = this.localeResolver.resolveLocale(request);
	response.setLocale(locale);
	View view;
	if (mv.isReference()) {
		//4.2.1视图解析
		view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
		...
	}
	else {
		view = mv.getView();
	}
	....
	try {
		if (mv.getStatus() != null) {
			response.setStatus(mv.getStatus().value());
		}
      	//渲染返回
		view.render(mv.getModelInternal(), request, response);
	}
	...
}
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
		HttpServletRequest request) throws Exception {
	//视图解析
	for (ViewResolver viewResolver : this.viewResolvers) {
		View view = viewResolver.resolveViewName(viewName, locale);
		if (view != null) {
			return view;
		}
	}
	return null;
}

过程概括:

  1. 调用HandlerMapping得到HandlerChain(Handler+Intercept)
  2. 调用HandlerAdapter执行handle过程(参数解析 过程调用)
  3. 异常处理(过程类似HanderAdapter)
  4. 调用ViewResolver进行视图解析
  5. 渲染视图

springmvc流程
上述图片来自网络