在servlet容器中当一个请求到来的时候servlet容器会把请求分配给servlet进行处理,我们知道spring-mvc是通过DispatcherServlet来处理请求,DispatcherServlet的类图如下
通过这个图片可以看到DispatcherServlet继承FrameworkServlet
在配置DispatcherServlet的时候要配置contextConfigLocation地址用来加载spring的配置文件
这个配置文件的初始化工作就是在FrameworkServlet中完成的
通过initServletBean完成初始化工作,加载spring配置文件
加载完成spring的配置文件后会生成webApplicationContext
当context生成后会调用onRefresh方法,而这个方法是在DispatcherServlet中实现的
它会执行如下代码
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
这段代码中可以看到,会初始化Resolver、Mapping、Adapter等类
servlet完成了初始化工作后,当接收一个请求的时候会调用DispatcherServlet 中的doService方法
这个方法会往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());
然后会执行doDispatch方法
在doDispatch()中首先检查这个request是否是包含文件的上传
如果是则创建MultipartHttpServletRequest
如下代码
processedRequest = checkMultipart(request);
然后主要会依次执行下面的代码
mappedHandler = getHandler(processedRequest, false);//根据request找到mappedHandler
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//根据mappedHandler找到对应的adapter
mappedHandler.applyPreHandle(processedRequest, response)//执行HandlerInterceptor的preHandle
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//生成ModelAndView
applyDefaultViewName(request, mv);//如果生成的ModelAndView为空,设置默认的ModelAndView
mappedHandler.applyPostHandle(processedRequest, response, mv);//执行HandlerInterceptor的postHandle
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);//进行渲染
根据上面的代码得到处理一个请求的主要步骤
1、根据request找到对应的HandlerExecutionChain
2、通过HandlerExecutionChain和request找到对应的HandlerAdapter
3、执行spring过滤器的preHandle
4、生成ModelAndView
5、设置默认的ModelAndView
6、执行spring过滤器的postHandle
7、根据ModelAndView进行渲染