步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理

文章目录

  • 步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
    • 继承关系
    • 入口 DispatcherServlet#doDispatch
    • 多文件上传解析
    • 获取处理器
    • handler的完整注册流程
    • 获取HandlerAdapter
    • 执行拦截器PreHandle
    • 执行HandlerAdapter.handle
    • 参数解析器HandlerMethodArgumentResolver
    • @RequestBody的实现逻辑
    • handler方法返回值处理器
    • @ResponseBody的实现逻辑
    • 执行拦截器postHandle
    • 执行拦截器的afterCompletion
    • 异常的处理
    • Spring MVC 学习笔记深入源码

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理

继承关系

image-20240627172315209

DispatcherServlet继承自最基础的HttpServlet

image-20240627172610774

DispatcherServlet父类FrameworkServlet中实现了dotGet、doPost等do方法,都是调用了processRequest(request, response);

image-20240627172722028

这方法里又调doService(request, response);

image-20240627172908166

又调了doDispatch(request, response); 开始转发请求

image-20240627172946905

入口 DispatcherServlet#doDispatch

image-20240627173359201

多文件上传解析

image-20240627145243034

processedRequest = checkMultipart(request);

代码就不贴了,很简单,自己可以点进去看,就检查method 为post,content type 是否以multipart/ 开头的,如果是则执行解析多文件上传请求,把文件封装为MultipartFile对象,设置在请求内部属性里MultiValueMap<String, MultipartFile> multipartFiles

image-20240627114043337

获取处理器

image-20240627145218364

mappedHandler = getHandler(processedRequest);

image-20240627114116385

平时我们写的@RequestMapping(“/xxx”)就是这个接口的一个实现:RequestMappingHandlerMapping

image-20240627114304017

打开这个类看可以看到Creates RequestMappingInfo instances from type and method-level @RequestMapping annotations in @Controller classes

注释写到 通过在@Controller类的方法中使用@RequestMapping来注册RequestMappingInfo实例

image-20240627114601617

handler的完整注册流程

我们看下这个是怎么注册的,搜索RequestMappingHandlerMapping的使用,找到这个地方注入的,WebMvcAutoConfiguration,这个类在

spring-boot-autoconfigure-2.2.3.RELEASE.jar这个包里

image-20240627143104034

先创建了RequestMappingHandlerMapping对象,再塞入拦截器等组件

image-20240627143456790

image-20240627143532869

而RequestMappingHandlerMapping继承了AbstractHandlerMethodMapping,AbstractHandlerMethodMapping这个实现了InitializingBean接口

image-20240627143720735

image-20240627143706012

在afterPropertiesSet方法里调用了初始化方法initHandlerMethods()

image-20240627143758352

拿到上下文容器里的所有bean,逐个处理,执行processCandidateBean

image-20240627143933584

判断这个bean是不是handler,如果是就执行detectHandlerMethods,去检测handler方法

image-20240627144042832

对类中的方法逐个执行getMappingForMethod,去拿RequestMappingInfo,这个方法不是的话就返回的null

image-20240627144141202

看下面两个代码图,你可以知道,是去检测了注解@RequestMapping,如果有就封装为RequestMappingInfo返回,没有就返回null。

image-20240627144220101

image-20240627144306883

image-20240627144728647

最后全部扫描完,注册上去

image-20240627144359848

image-20240627144420840

可以看到最后其实就是放到了MappingRegistry类的属性map里存着了

image-20240627144502778

image-20240627144550203

获取HandlerAdapter

image-20240627145330059

实际上内部就是逐个HandlerAdapter调了下supports方法看是不是支持,谁支持就返回谁

image-20240627145351118

我们看到,这个handler适配器总共就只有几种的

image-20240627145406636

image-20240627145428686

我们这种HandlerMethod适用于这个适配器

image-20240627145550276

执行拦截器PreHandle

image-20240627145818696

循环执行这个methodHandler要使用的拦截器interceptor的preHandle

image-20240627145942141

执行HandlerAdapter.handle

image-20240627150052815

handle又直接调了handleInternal

image-20240627150138209

执行invokeHandlerMethod

image-20240627150252963

invokeHandlerMethod方法里把要的一些组件封装为一个ServletInvocableHandlerMethod,然后执行invocableMethod.invokeAndHandle(webRequest, mavContainer);

image-20240627150637386

调用invokeForRequest执行请求

image-20240627150919741

获取参数

image-20240627151001584

参数解析器HandlerMethodArgumentResolver

image-20240627151046687

@RequestBody的实现逻辑

参数解析器的接口,判断是否支持这个参数,以及解析参数的方法,有个常用的参数解析器,@RequestBody,我们探究下它的实现

image-20240627170435089

查看实现类,搜body,就只剩这个了,进去看就是它

image-20240627170648980

判断是否有注解@RequestBody

image-20240627170732033

我们看这个readWithMessageConverters

image-20240627171131777

又调用了readWithMessageConverters来使用MessageConverter解析消息,底层使用了MappingJackson2HttpMessageConverter来解析,这也是为啥直接写个对象,然后用@RequestBody注解就能解析好请求的Body参数。后面还会讲解@ResponseBody实现原理。

image-20240627171153849

image-20240627171250174

执行目标方法

image-20240627151149268

handler方法返回值处理器

有个比较常见的返回值处理器就是RequestResponseBodyMethodProcessor

image-20240627151230244

这个是HandlerMethodReturnValueHandler接口,用来对handler方法返回值做处理

image-20240627162235268

@ResponseBody的实现逻辑

常用的@ResponseBody就是在这实现的

image-20240627162412084

我们看下它的处理方法

image-20240627162447978

继续进writeWithMessageConverters方法

image-20240627163602656

我们看看HttpMessageConverter

image-20240627163658942

就几个很简单的方法,能不能读,能不能写,读,写方法。看看实现类

image-20240627163731945

我们看其中一个

image-20240627164831079

继承了AbstractJackson2HttpMessageConverter,那四个接口方法都是在AbstractJackson2HttpMessageConverter实现的,我们去看看

image-20240627165035048

内部使用的ObjectMapper来实现的读写

image-20240627165212771

image-20240627165237581

执行拦截器postHandle

image-20240627161515884

image-20240627161552845

执行拦截器的afterCompletion

image-20240627161657838

执行异常拦截器、拦截器interceptors的afterCompletion

image-20240627161808488

至此,HandlerInterceptor的preHandle、postHandle、afterCompletion全部执行完了

image-20240627161857048

异常的处理

查看我的另一个异常专篇 springmvc 全局异常处理器配置的三种方式&深入底层源码分析原理

Spring MVC 学习笔记深入源码

Spring MVC 学习笔记深入源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/750465.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

抖音外卖服务商有哪些,盘点这几家正规服务商!

当前&#xff0c;抖音外卖的关注度不断上涨&#xff0c;抖音外卖服务商也逐渐成为了众多创业者心中的理想创业赛道。在此背景下&#xff0c;抖音外卖服务商的入局途径多次引发创业者热议&#xff0c;以抖音外卖服务商有哪些公司为代表的相关话题更是长期位居创业者问题榜单的前…

走进机器学习

第1关&#xff1a;走进机器学习 机器学习简介 机器学习近年来被大规模应用在各种领域&#xff0c;特别是 NLP 领域。虽然机器学习是门建立在统计和优化上的新兴学科&#xff0c;但是在自然语言处理、数据科学等领域&#xff0c;它却占据着核心的地位。 图 1 机器学习最初的研…

论文降重困难重重?AI降重来帮忙

论文查重和降重是确保学术成果原创性及学术诚信的关键步骤&#xff0c;直接影响我们的学业成果和毕业资格。传统的论文查重方法主要包括使用查重软件和个人自查&#xff0c;而论文降重通常涉及改写、使用同义词替换、内容的扩展和深化&#xff0c;以及正确的引用和注释等方式来…

企业数据治理的下一步是数据资产管理?

随着信息技术的飞速发展和数字化转型的深入推进&#xff0c;企业数据已成为驱动业务增长和创新的核心要素。当企业数据治理工作取得显著成效后&#xff0c;如何进一步发挥数据的价值&#xff0c;实现数据资产的有效管理&#xff0c;成为企业面临的重要课题。 数据治理的基石作用…

记录一次OPDS trunc()函数使用错误

说明&#xff1a;本文介绍 场景 在一次SQL查询时&#xff0c;需要对结果值保留两位小数&#xff0c;不四舍五入&#xff0c;直接截取到小数点后两位。如 59.156到59.15&#xff0c;23.2134到23.21&#xff0c;查看官方帮助文档&#xff08;https://help.aliyun.com/zh/maxcom…

8个Unity开发高手都在用的秘密技巧!

1. 不要重新发明轮子&#xff0c;使用内置的引擎工具 在使用任何引擎时&#xff0c;比如Unity或Unreal Engine&#xff0c;一些开发者&#xff0c;主要是来自计算机科学领域的开发者&#xff0c;可能会倾向于从头开始开发大型算法或结构&#xff0c;而不去了解引擎中是否已经存…

多线程(基础)

前言&#x1f440;~ 上一章我们介绍了什么是进程&#xff0c;对于进程就了解那么多即可&#xff0c;我们作为java程序员更关注线程&#xff0c;线程内容比较多&#xff0c;所以我们要分好几部分才能讲完 目录 进程的缺点 多线程&#xff08;重要&#xff09; 进程和线程的区…

数据分析必备:一步步教你如何用matplotlib做数据可视化(14)

1、Matplotlib 图像 Matplotlib包中的图像模块提供加载&#xff0c;重新缩放和显示图像所需的功能。Pillow库支持加载图像数据。Matplotlib仅支持PNG图像。如果本机读取失败&#xff0c;下面显示的命令将回退到Pillow。 此示例中使用的图像是PNG文件&#xff0c;但请记住数据的…

计算机网络之奇偶校验码和CRC冗余校验码

今天我们来看看有关于计算机网络的知识——奇偶校验码和CRC冗余校验码&#xff0c;这两种检测编码的方式相信大家在计算机组成原理当中也有所耳闻&#xff0c;所以今天我就来跟大家分享有关他们的知识。 奇偶校验码 奇偶校验码是通过增加冗余位使得码字中1的个数恒为奇数或偶数…

JS在线加密简述

JS在线加密&#xff0c;是指&#xff1a;在线进行JS代码混淆加密。通过混淆、压缩、加密等手段&#xff0c;使得JS源代码难以阅读和理解。从而可以有效防止代码被盗用或抄袭&#xff0c;保护开发者的知识产权和劳动成果。常用的JS在线加密网站有&#xff1a;JShaman、JS-Obfusc…

AI写作助力:如何用AI降重工具快速提升论文原创性?

高查重率是许多毕业生的困扰。通常&#xff0c;高查重率源于过度引用未经修改的参考资料和格式错误。传统的降重方法&#xff0c;如修改文本和增添原创内容&#xff0c;虽必要但耗时且成效不一。 鉴于此&#xff0c;应用AI工具进行AIGC降重成为了一个高效的解决方案。这些工具…

线性相关,无关?秩?唯一解(只有零解),无穷解(有非零解)?D=0,D≠0?

目录 线性有关无关 和 唯一解&#xff08;只有零解&#xff09;&#xff0c;无穷解&#xff08;有非零解&#xff09;之间的关系 D0&#xff0c;D≠0&#xff1f; 和 秩 的关系 串起来&#xff1a; 线性相关&#xff0c;无关&#xff1f;秩&#xff1f;唯一解&#xff08;只…

cuda 学习笔记4

一 基本函数 在GPU上开辟空间&#xff0c;无论定义的数据是float还是int ,还是****gpu_int,分配空间的函数都是下面固定的形式 (void**)& 1.函数定义&#xff0c;global void 是配套使用的&#xff0c;是在GPU上定义&#xff0c;也就是GPU上执行&#xff0c;CPU上调用的函数…

【软件测试】白盒测试与接口测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是白盒测试 白盒测试是一种测试策略&#xff0c;这种策略允许我们检查程序的内部结构&a…

短视频带货实战营(高阶课),从0到1做个赚钱的抖音号(17节课)

课程目录&#xff1a; 1-短视频带贷先导课_1.mp4 2-账号搭建_1.mp4 3-账号养号涨粉套路_1.mp4 4-开通橱窗_1.mp4 5-管家式选品_1.mp4 6-六个能赚钱的赛道_1.mp4 7-选品之精选联盟_1.mp4 8-好物分享的三种形式_1.mp4 9-短视频之图文课_1.mp4 10-短视频之剪辑课_1.mp4 …

el-upload+python fastAPI实现上传文件

el-upload通过action指定后端接口&#xff0c;并通过name指定传输的文件包裹在什么变量名中 <el-uploadclass"upload-demo"dragaction"https://ai.zscampus.com/toy/upload"multiplename"fileList":limit"10"accept".xlsx, .x…

昇思25天学习打卡营第9天|使用静态图加速

一、简介&#xff1a; AI编译框架分为两种运行模式&#xff0c;分别是动态图模式以及静态图模式。MindSpore默认情况下是以动态图模式运行&#xff0c;但也支持手工切换为静态图模式。两种运行模式的详细介绍如下&#xff1a; &#xff08;1&#xff09;动态图&#xff1a; …

如何使用Hugging Face Transformers为情绪分析微调BERT?

情绪分析指用于判断文本中表达的情绪的自然语言处理(NLP)技术&#xff0c;它是客户反馈评估、社交媒体情绪跟踪和市场研究等现代应用背后的一项重要技术。情绪可以帮助企业及其他组织评估公众意见、提供改进的客户服务&#xff0c;并丰富产品或服务。 BERT的全称是来自Transfo…

The First Descendant第一后裔联机失败、联机报错这样处理

第一后裔/The First Descendant是一款免费的多人合作射击游戏&#xff0c;玩家将进入一片混乱的英格里斯大陆&#xff0c;扮演继承者后裔&#xff0c;通过各种主支线任务和故事剧情触发&#xff0c;最终揭开自身的秘密&#xff0c;并带领大家一起抵抗邪恶势力的入侵。为了避免玩…

【Java Web】三大域对象

目录 一、域对象概述 二、三大域对象 三、域对象使用相关API 一、域对象概述 一些可用于存储数据和传递数据的对象被称为域对象&#xff0c;根据传递数据范围的不同&#xff0c;我们称之为不同的域&#xff0c;不同的域对象代表不同的域&#xff0c;共享数据的范围也不同。 二、…