在面试的时候,面试官经常会问你对SpringMVC了解吗?大多数面试者多会说出SpringMVC的执行流程图,其实我觉得这也没有错,毕竟SpringMVC就是按照这一套流程执行的,下面就是该执行流程图:
今天我们就从源码的角度来看它到底是怎么执行的?下面这段代码它是DispatchServlet类中的doDispatch()方法,也就是我们上图的前端控制器
1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 HttpServletRequest processedRequest = request; 3 HandlerExecutionChain mappedHandler = null; 4 boolean multipartRequestParsed = false; 5 WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 6 7 try { 8 try { 9 ModelAndView mv = null; 10 Object dispatchException = null; 11 12 try { 13 processedRequest = this.checkMultipart(request); 14 multipartRequestParsed = processedRequest != request; 15 mappedHandler = this.getHandler(processedRequest); 16 if (mappedHandler == null) { 17 this.noHandlerFound(processedRequest, response); 18 return; 19 } 20 21 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler()); 22 String method = request.getMethod(); 23 boolean isGet = "GET".equals(method); 24 if (isGet || "HEAD".equals(method)) { 25 long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); 26 if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) { 27 return; 28 } 29 } 30 31 if (!mappedHandler.applyPreHandle(processedRequest, response)) { 32 return; 33 } 34 35 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 36 if (asyncManager.isConcurrentHandlingStarted()) { 37 return; 38 } 39 40 this.applyDefaultViewName(processedRequest, mv); 41 mappedHandler.applyPostHandle(processedRequest, response, mv); 42 } catch (Exception var20) { 43 dispatchException = var20; 44 } catch (Throwable var21) { 45 dispatchException = new NestedServletException("Handler dispatch failed", var21); 46 } 47 48 this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException); 49 } catch (Exception var22) { 50 this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22); 51 } catch (Throwable var23) { 52 this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23)); 53 } 54 55 } finally { 56 if (asyncManager.isConcurrentHandlingStarted()) { 57 if (mappedHandler != null) { 58 mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); 59 } 60 } else if (multipartRequestParsed) { 61 this.cleanupMultipart(processedRequest); 62 } 63 64 } 65 }
下图就是该方法重要的第一步,获取执行链
执行链中包含两个重要的属性,一个是handler(上图所说的handler),另一个是HandlerInterceptor(拦截器),下面再说这两个的属性
进入getHandler()方法
四种HandlerMapping:
DefaultAnnotationHandlerMapping;
SimpleUrlHandlerMapping;
BeanNameUrlHandlerMapping;
ControllerClassNameHandlerMapping。