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等。