前言
本文旨在介绍SpringMVC的源码分析思路,注重整体思路及流程
一、SpringMVC执行流程
二、源碼分析
以上在DispatcherServlet
里,有九个成员变量是九大组件,下面一一介绍
/** 用于解析文件的文件解析器,实现了文件上传功能 */
@Nullable
private MultipartResolver multipartResolver;/** 国际化资源解析器,处理国际化资源切换语言的 */
@Nullable
private LocaleResolver localeResolver;/** 主题解析器,切换主题样式 */
@Nullable
private ThemeResolver themeResolver;/** 处理器的映射器,用于根据请求路径查找Controller里的方法(Handler) */
@Nullable
private List<HandlerMapping> handlerMappings;/** 处理器的适配器,用于调用不同的handler方法的 */
@Nullable
private List<HandlerAdapter> handlerAdapters;/** 异常处理器,用于统一处理异常的 */
@Nullable
private List<HandlerExceptionResolver> handlerExceptionResolvers;/** 视图名称转换器,如果Handler里没有返回视图名称,会由这个转换器提供一个默认的视图名称 */
@Nullable
private RequestToViewNameTranslator viewNameTranslator;/** FlashMap管理器,用于在重定向跳转时传参的 */
@Nullable
private FlashMapManager flashMapManager;/** 视图解析器,用于解析视图的 */
@Nullable
private List<ViewResolver> viewResolvers;
初始化方法:
前端控制器执行时,最终会调用到doDispatch()方法:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
......
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//1. 如果是上传文件,处理文件数据
processedRequest = checkMultipart(request);
.......
//2. 根据请求路径,查找对应的Handler(查找Controller里的方法,得到HandlerExecutionChain)
mappedHandler = getHandler(processedRequest);
......
//3. 查找当前请求对应的处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
......
//4. 调用拦截器的preHandle方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//5. 直接调用处理器方法(调用Controller里的方法,得到返回值ModelAndView)
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
......
//6. 如果处理器方法没有返回视图路径,在这里给提供一个默认的视图路径
applyDefaultViewName(processedRequest, mv);
//7. 调用拦截器的postHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception ex) {
dispatchException = ex;
} catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
//8. 查找视图、渲染视图。在渲染视图之后,返回响应之前,调用拦截器的afterCompletion方法
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
以上是SpringMVC的执行流程及入口介绍,如果想了解各部分实现细节,可以在入口追进去看源码