当前位置: 首页 > article >正文

【源码解读】SpringMMVC执行流程

直接进入主题,当我们执行一条请求的时候,是会进入到org.springframework.web.servlet.DispatcherServlet类的doDispatch方法中

 

这个方法是从HandleMapping中获取对应的Handle

 

其实就是得到我们需要执行的某个方法 接下来判断这个mapperhandle是否为空

 

如果没有匹配到相对应的handle,就会执行this.noHandlerFound()方法

 

令人恶心的404

如果有对应的handle,那么此时就要获取对应的HandlerAdapter

 

接下来看下这行代码

 

 

这行代码的作用是执行springMvc的拦截器链的前置方法,如果前置方法返回fasle,那么取反就是true,那么直接return。至于这个拦截器链怎么得到的我在下一篇文章说明

接下来看下下面这个方法

 

 

 

在invokeHandlerMethod方法中有一行代码

 

进入这个方法

 

这里标记了二个方法,

Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);

这个方法的原理就是首先获取方法参数,然后遍历参数看是否有@RequestBody注解,接着获取HTTP中body中的内容,如果参数是个实体类,那么就会调用对应的setter方法进行赋值,将值设置到参数中去。

接下来看下处理返回值的方法

this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest);

 

首先看下下面这个方法

HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);

 

我们看下如果没有加@ResponseBody注解是返回一个怎么样的HandlerMethodReturnValueHandler

 

返回的是ViewNameMethodReturnValueHandle,如果添加了@ResponseBody返回的是不一样的

接下来看下下面这个方法

handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);

进入到org.springframework.web.servlet.mvc.method.annotation.ViewNameMethodReturnValueHandler类中的handleReturnValue方法

 

 

这个viewName就是我们方法返回的页面的名称,在这里将这个值设置好,设置好之后就回到org.springframework.web.servlet.DispatcherServlet的doDispatch()方法

 

刚刚我们是分析了下面这个方法

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

接下来分析下

this.applyDefaultViewName(processedRequest, mv);

这个方法有个mv的参数,看下值是什么

 

其实就是ModelAndView对象,并且将我们要返回的页面的名称设置进去,刚刚解析过了是怎么设置的,然后进入这个方法

 

这个方法是说mv这个对象不为空,但是没有返回的具体页面,那么就设置成默认的返回页面

 

 

看出来这是执行拦截器的后置处理方法的,接下来看下doDispatch()最后一个方法,如下图

 

 

 

最后一直进入到org.springframework.web.servlet.view.InternalResourceView类的renderMergedOutputModel()方法

 

最后执行RequestDispatcher.forward()来实现页面跳转。这是没有@ResponseBody注解的,接下里看下有@ResponseBody注解时候是怎么实现的。还记得之前处理返回结果的方法嘛??

 

 

记得上面解析不带@ResponseBody注解时候返回的返回的是ViewNameMethodReturnValueHandle,现在有这个注解看下返回的是什么

 

返回的是不一样的,那么为什么会不一样呢??看下上面这幅图的if判断

  if(handler.supportsReturnType(returnType))

它就是判断当前类上或者方法上是否有@ResponseBody注解的

我们继续看下下面这个方法

handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);

它是执行了org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor类中的handleReturnValue方法

 

接下来会进入到org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor类中的下面这个方法

 

在这个方法的最后几行的样子有这样一个方法

 

 

 

 

最后用OutPutStream.write()将我们的结果返回


http://www.kler.cn/a/429504.html

相关文章:

  • 智能科技与共情能力加持,哈曼重新定义驾乘体验
  • 浅谈云计算07 | 云安全机制
  • vue3 uiapp实现一个数字输入组件, 舒服非数字会默认转成最小数
  • Vue2+OpenLayers调用WMTS服务初始化天地图示例(提供Gitee源码)
  • lerna使用指南
  • ImportError: attempted relative import with no known parent package 报错的解决!
  • 教程|使用Conda安装AlphaFold3-个人记录以及遇到的问题
  • CLIP论文提炼与代码实战
  • node.js 环境配置
  • leetcode207:课程表
  • C#的基本类型,一篇很基础的文章
  • NLP-实体识别
  • Linux,如何要定位并删除占用磁盘空间的大文件?
  • 换一个ip地址是什么意思?换一个网络ip地址会变吗
  • AI如何让PPT制作变得轻松与智能?用一键生成ppt!
  • HTML DOM API
  • MFC中如何创建一个非模态对话框
  • TEA系列例题
  • 开源轻量级文件分享服务Go File本地Docker部署与远程访问
  • 使用docker-compose安装Milvus向量数据库及Attu可视化连接工具
  • 物理学:什么是核聚变?
  • .Net学习
  • el-dialog修改其样式不生效加deep也没用
  • 从零用java实现 小红书 springboot vue uniapp (1)
  • 探索数据确权、隐私保护、安全共享等方面的挑战与解决方案
  • IDEA离线安装activit bpmn 插件