springMVC执行流程一、springMVC执行流程1、起源MVC架构主要由模型层、视图层和控制器层组成。1.1、jsp模型主要是结构简单,开发这个小项目效率高,主要由这个jsp和javaBean组成。但是jsp同时负责controller层和view层,所以所有的代码都写在这个jsp里面,导致这段代码复用性低,维护不方便,所以淘汰了这个架构。1.2、servlet模型改进了之前的模型,将controller层和view层分离,让各部分各司其职。请求由controller控制器完成,jsp专门用来展示数据,提高了代码的复用性和易维护性。2、SpringMVC执行流程1、客户端向DispatcherServlet前端控制器发送请求2、前端控制器会通过HandlerMapping处理器映射器找到合适的handler,即通过输入的url找到对应的handler3,以及return处理器的执行链会包含多个拦截器的信息和需要查找的处理器处理程序的信息。4.找到处理器适配器HandlerAdapter。这一步开始的时候会调用handler中的方法5,通过执行这个handler里面的方法会找到具体的controller方法6,找到具体的controller后,会返回一个modelAndView给HanderAdapter给processoradapter7.processoradapter获取到ModelAndView后,会将结果返回给DispatcherServlet前端控制器8.通过ViewResolver视图解析器解析ModelAndView9。解析完成后,view会返回给前端DispatcherServlet前端控制器10,model中的数据会填充到view视图中,最后渲染view。二、源码分析1、首先打开DispatcherServlet类,可以发现该类继承了FrameworkServletpublicclassDispatcherServletextendsFrameworkServlet{...}2、该类中有一个doService方法,还有一个比较重要的方法调用doDispatch方法的方法doDispatch(request,response);3、进入doDispatch()方法,可以看到如下几行代码,主要是返回处理器执行链、处理器适配器等操作。//Processor执行链HandlerExecutionChainmappedHandler=null;//检测当前请求是否需要做文件上传==null){noHandlerFound(processedRequest,response);return;}//找到这个处理器适配器HandlerAdapterha=getHandlerAdapter(mappedHandler.getHandler());//调用拦截器mappedHandler.applyPreHandle(processedRequest,response);//Adapter开始调用这个handlermv=ha.handle(processedRequest,response,mappedHandler.getHandler());//处理这个结果集processDispatchResult(processedRequest,response,mappedHandler,mv,dispatchException);4、后面的所有分析都是基于这个doDispatch()方法,对里面的方法做具体的描述。接下来看这个getHandler方法,主要是通过这个request请求来获取对应的handler。protectedHandlerExecutionChaingetHandler(HttpServletRequestrequest)throwsException{if(this.handlerMappings!=null){//遍历所有获取到的handlermappersfor(HandlerMappinghm:this.handlerMappings){//通过thisrequest匹配找到ThishandlerHandlerExecutionChainhandler=hm.getHandler(请求);//如果找到,返回if(handler!=null){returnhandler;}}}returnnull;}5、我们看一下这个获取handler适配器getHandlerAdapter的方法,适配器也有很多种,根据不同的handler会适配不同的适配器。protectedHandlerAdaptergetHandlerAdapter(Objecthandler)throwsServletException{if(this.handlerAdapters!=null){for(HandlerAdapterha:this.handlerAdapters){if(ha.supports(handler)){返回ha;}}}thrownewServletException();}6、查看这个doDispatch方法中的handle方法,可以点击查找具体实现如下。最后会返回一个控制器对象publicModelAndViewhandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{//作为控制器返回return((Controller)handler).handleRequest(request,response);}7、可以自定义重写handleRequest方法,最后以ModelAndView的形式返回给处理适配器,处理器适配器将ModelAndView返回给前端控制器。@OverridepublicModelAndViewhandleRequest(HttpServletRequest请求,HttpServletResponse响应)抛出异常{ModelAndViewmv=newModelAndView();mv.setViewName("成功");mv.addObject("你好","zhs");returnmv;}8、接下来我们看一下前端控制器是如何处理ModelAndView的视图分析的,主要是通过processDispatchResult方法。if(mv!=null&&!mv.wasCleared()){//如果这个modelAndView不为空,则开始进入正式解析render(mv,request,response);如果(errorView){WebUtils.clearErrorRequestAttributes(请求);}}再次进入render方法,可以发现视图解析器会对视图进行特定的解析,并将解析后的视图返回给DispatcherServlet,最后转发或重定向数据,渲染视图,最后响应客户端。//会进行具体分析getRequestToExpose(request),response);//转发或重定向获取到的数据RequestDispatcherrd=getRequestDispatcher(request,dispatcherPath);
