Spring MVC 申请解决流程
用户发动申请,到 DispatcherServlet;
而后到 HandlerMapping 返回处理器链(蕴含拦截器和具体解决的 Handler);
调用处理器链的适配器 HandlerAdapter 来解决;
执行具体的办法,比方 @RequestMapper 润饰的逻辑解决办法;
返回后果的视图解析器;
最初进行视图解析和渲染返回后果给用户;
DispatcherServlet
DispatcherServlet 是前置控制器,配置在 web.xml 文件中的。拦挡匹配的申请,Servlet 拦挡匹配规定要本人定义,把拦挡下来的申请,根据相应的规定散发到指标 Controller 来解决,是配置 spring MVC 的第一步。
DispatcherServlet 是前端控制器设计模式的实现,提供 Spring Web MVC 的集中拜访点,而且负责职责的分派,而且与 Spring IoC 容器无缝集成,从而能够取得 Spring 的所有益处。
源码剖析
org.springframework.web.servlet.DispatcherServlet#doDispatch 办法是次要解决申请的源码如下:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
try {
// 文件上传相干
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// DispatcherServlet 收到申请调用处理器映射器 HandlerMapping。// 处理器映射器依据申请 url 找到具体的处理器,生成处理器执行链 HandlerExecutionChain(包含处理器对象和处理器拦截器)一并返回给 DispatcherServlet。mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {noHandlerFound(processedRequest, response);
return;
}
4.DispatcherServlet 依据处理器 Handler 获取处理器适配器 HandlerAdapter,
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler. HTTP 缓存相干
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}
}
// 前置拦截器
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
// 返回 false 就不进行后续解决了
return;
}
// 执行 HandlerAdapter 解决一系列的操作,如:参数封装,数据格式转换,数据验证等操作
// 执行处理器 Handler(Controller,也叫页面控制器)。// Handler 执行实现返回 ModelAndView
// HandlerAdapter 将 Handler 执行后果 ModelAndView 返回到 DispatcherServlet
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {return;}
// 如果没有视图,给你设置默认视图 json 疏忽
applyDefaultViewName(processedRequest, mv);
// 后置拦截器
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);
}
// DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器
// ViewReslover 解析后返回具体 View
// DispatcherServlet 对 View 进行渲染视图(行将模型数据 model 填充至视图中)。// DispatcherServlet 响应用户。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);
}
}
}
}
复制代码
在 doDispatch 方中曾经涵盖了 DispatcherServlet 的主要职责:
1、文件上传解析,如果申请类型是 multipart 将通过 MultipartResolver 进行文件上传解析;
2、通过 HandlerMapping,将申请映射到处理器(返回一个 HandlerExecutionChain,它包含一个处理器、多个 HandlerInterceptor 拦截器);
3、通过 HandlerAdapter 反对多种类型的处理器 (HandlerExecutionChain 中的处理器);
4、通过 ViewResolver 解析逻辑视图名到具体视图实现;
5、本地化解析;
6、渲染具体的视图等;
7、如果执行过程中遇到异样将交给 HandlerExceptionResolver 来解析。
DispatcherServlet 初始化的上下文加载的 Bean 是只对 SpringMVC 无效的 Bean,
如 Controller、HandlerMapping、HandlerAdapter 等等,该初始化上下文只加载 Web 相干组件。
DispatcherServlet 初始化次要做了如下两件事件:
1、初始化 SpringMVC 应用的 Web 上下文,并且可能指定父容器为(ContextLoaderListener 加载了根上下文);
2、初始化 DispatcherServlet 应用的策略,如 HandlerMapping、HandlerAdapter 等。