首页 > 编程语言 >SpringMVC源码(五):MVC请求执行整体源码概览

SpringMVC源码(五):MVC请求执行整体源码概览

时间:2023-02-24 20:37:09浏览次数:53  
标签:请求 SpringMVC mappedHandler request response MVC 源码 processedRequest

一、SpringMVC源码分析搭建

  源码(一):MVC源码分析工程搭建

二、SpringMVC容器启动

  源码(二):MVC容器启动

  源码(三):MVC九大内置组件初始化

二、MVC整体请求流程

一、请求流程入口分析

  源码(四):MVC请求流程入口

二、请求分发处理

  请求分发处理,DispatcherServlet#doDispatch() 核心伪代码

 1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
 2    // 实际处理时所用的request,如果不是上传请求,则直接使用接收到的request,否则封装成上传类型的request
 3    HttpServletRequest processedRequest = request;
 4    // 处理请求的处理器链(包含处理器和对应的interceptor)
 5    HandlerExecutionChain mappedHandler = null;
 6    // 是不是上传请求的标志
 7    boolean multipartRequestParsed = false;
 8 
 9    // 获取异步管理器
10    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
11 
12    try {
13       // 封装model和view的容器
14       ModelAndView mv = null;
15       // 处理请求过程中抛出的异常,但是不包含渲染过程中抛出的异常
16       Exception dispatchException = null;
17 
18       try {
19          // 检测请求是否为上传请求,如果是则通过multipartResolver将其封装成MultipartHttpServletRequest对象
20          processedRequest = checkMultipart(request);
21          // 设置上传请求的标志
22          multipartRequestParsed = (processedRequest != request);
23 
24          // HandlerMapping组件,获得请求对应的HandlerExecutionChain对象(HandlerMethod和HandlerInterceptor拦截器集)
25          mappedHandler = getHandler(processedRequest);
26          //  如果获取不到,则根据配置抛出异常或返回404错误
27          if (mappedHandler == null) {
28             noHandlerFound(processedRequest, response);
29             return;
30          }
31          //  HandlerAdapter组件,获得当前handler对应的HandlerAdapter对象
32          HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
33 
34          // 执行响应Interceptor的前置处理preHandler
35          if (!mappedHandler.applyPreHandle(processedRequest, response)) {
36             return;
37          }
38 
39          // 真正的调用handler方法,也就是执行对应的方法,并返回视图
40          mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
41 
42          // 如果需要异步处理,直接返回
43          if (asyncManager.isConcurrentHandlingStarted()) {
44             return;
45          }
46 
47          // 当view为空时,根据request设置默认的view
48          applyDefaultViewName(processedRequest, mv);
49          // 执行响应的interceptor的postHandler方法
50          mappedHandler.applyPostHandle(processedRequest, response, mv);
51       }
52       catch (Exception ex) {
53          // 记录异常
54          dispatchException = ex;
55       }
56       catch (Throwable err) {
57          // 初始化dispatchException异常
58          dispatchException = new NestedServletException("Handler dispatch failed", err);
59       }
60       // 处理返回结果,包括处理异常、渲染页面、触发Interceptor的afterCompletion
61       processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
62    }
63    catch (Exception ex) {
64       // 已完成处理 拦截器
65       triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
66    }
67    catch (Throwable err) {
68       // 完成处理激活触发器
69       triggerAfterCompletion(processedRequest, response, mappedHandler,
70             new NestedServletException("Handler processing failed", err));
71    }
72    finally {
73       // 判断是否执行异步请求
74       if (asyncManager.isConcurrentHandlingStarted()) {
75          // Instead of postHandle and afterCompletion
76          if (mappedHandler != null) {
77             mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
78          }
79       }
80       else {
81          // Clean up any resources used by a multipart request.
82          // 清除上传请求的资源
83          if (multipartRequestParsed) {
84             cleanupMultipart(processedRequest);
85          }
86       }
87    }
88 }

2.1、上传请求的判断

  1、multipartResolver初始化

  2、文件上传处理器请求处理

2.2、获取Handler处理器

``源码(六):Handler处理器获取

2.3、获取HandlerAdapter适配器

``源码(七):HandlerAdapter适配器获取

2.4、执行目标Handler处理器及返回结果ModelAndView获取

``源码(八):执行Controller控制器流程

2.5、执行Controller控制器过程中无异常的View视图解析

``源码(九):无异常View视图解析

2.6、执行Controller控制器过程中有异常的View视图解析

``源码(十):异常View视图的处理

 

标签:请求,SpringMVC,mappedHandler,request,response,MVC,源码,processedRequest
From: https://www.cnblogs.com/RunningSnails/p/17152999.html

相关文章

  • 树莓派源码内核配置(二)
    再多嘴一句:树莓派LINUX源码配置,是为了驱动代码的编写,驱动代码编译需要一个提前编译好的内核,编译内核就必须配置,配置的最终目标是形成.config文件,该文件知道makefile去把有......
  • mvcc原理浅析
     在可重复读隔离级别,当事务开启,执行任何查询sql时会生成当前事务的一致性视图read-view,该视图在事务结束之前都不会变化(如果是读已提交隔离级别在每次执行查询sql时都会......
  • SkeyeLive开源流媒体同屏直播软件源码功能框架解析
    SkeyeLive是OpenSKEYE开源流媒体团队开发的一款功能丰富的开源PC端流媒体推流拉流直播软件项目,目前支持Windows、Android版本,后续将支持ios版本,其中Windows版本的SkeyeLive......
  • 快速搭建lamp环境以及httpd无法解析PHP文件,只显示PHP源码或者直接下载PHP文件的错误处
      快速搭建lamp环境以及httpd无法解析PHP文件,只显示PHP源码或者直接下载PHP文件的错误处理快速搭建lamp,使用yum安装httpd2.4以及mariadb10.1和php5.4,仅仅是测试学习用lam......
  • 调式源码解决 seata 报错 can not get cluster name 问题
    最近在使用SpringCloud整合分布式事务seata,项目启动之后,控制台一直报错:cannotgetclusternameinregistryconfig'service.vgroupMapping.nacos-provide-order-sea......
  • vue源码分析-从new Vue开始
    初学vue,你得知道我们是从newVue开始的:newVue({el:'#app',data:obj,...})那你觉得是不是很有意思,咱们newVue之后,就可以使用他那么多的功能,可见Vue是暴出......
  • 深入学习java源码之File类
    File类的常用方法①、创建方法1.booleancreateNewFile()不存在返回true存在返回false2.booleanmkdir()创建目录,如果上一级目录不存在,则会创建失......
  • Math类和StrictMath类源码详解
    Math类和StrictMath类源码详解类的定义publicfinalclassMath{}publicfinalclassStrictMath{}被final修饰的类不能被继承,即它不能拥有自己的子类Math类会提供一些三......
  • java的数组与Arrays类源码详解
    java的数组与Arrays类源码详解java.util.Arrays类是JDK提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用。类的定义......
  • java的StringBuilder与StringBuffer类源码详解
     java的StringBuilder与StringBuffer类源码详解类的定义abstractclassAbstractStringBuilderimplementsAppendable,CharSequence{char[]value;intcount;......