面试官:讲一讲Spring MVC源码解析
好看的皮囊千篇一律、有趣的灵魂万里挑一
文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。还有机会获得内推名额。

文章目录
- Spring MVC 源码解析
- 1. DispatcherServlet
- 2. HandlerMapping
- 3. HandlerAdapter
- 4. ViewResolver
- 5. ModelAndView
- 总结
Spring MVC 源码解析
Spring MVC 是 Spring 框架的核心组件之一,用于构建基于 Web 的应用程序。它实现了 Model-View-Controller(MVC)模式,使开发者可以方便地管理业务逻辑、视图和数据交互。以下是 Spring MVC 请求处理的主要流程及源码解析。
1. DispatcherServlet
DispatcherServlet 是 Spring MVC 的中央控制器,所有的 HTTP 请求都会先到达 DispatcherServlet。它负责协调请求的处理流程。
在 DispatcherServlet 的 doDispatch() 方法中,定义了处理请求的核心逻辑:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;ModelAndView mv = null;Exception dispatchException = null;try {// 1. 获取处理器(Handler)mappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// 2. 获取处理器适配器(HandlerAdapter)HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// 3. 执行前置拦截器(PreHandler Interceptor)if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 4. 执行处理器(Handler)逻辑,生成 ModelAndViewmv = ha.handle(processedRequest, response, mappedHandler.getHandler());// 5. 执行后置拦截器(PostHandler Interceptor)mappedHandler.applyPostHandle(processedRequest, response, mv);} catch (Exception ex) {dispatchException = ex;} catch (Throwable err) {dispatchException = new NestedServletException("Handler dispatch failed", err);} finally {// 6. 处理结果并渲染视图processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}
}
该方法的执行流程如下:
1、获取处理器:通过 getHandler() 方法,根据请求 URL 获取适当的处理器(Handler),通常是一个 Controller。
2、获取适配器:通过 getHandlerAdapter() 获取对应处理器的适配器(HandlerAdapter),负责调用具体的处理器方法。
3、执行前置拦截器:调用拦截器链的 applyPreHandle() 方法。
4、处理请求:调用 HandlerAdapter 的 handle() 方法,执行业务逻辑,并返回 ModelAndView 对象。
5、执行后置拦截器:调用拦截器链的 applyPostHandle() 方法。
6、渲染视图:调用 processDispatchResult() 进行结果处理,包括视图渲染。
2. HandlerMapping
HandlerMapping 负责根据请求 URL 映射到对应的处理器。Spring MVC 中常用的 HandlerMapping 实现有:
RequestMappingHandlerMapping:处理基于注解的映射(如 @RequestMapping)。
RequestMappingHandlerMapping 的核心逻辑是在 getHandlerInternal() 方法中根据请求查找相应的 Handler:
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {// 根据请求的 URL 查找对应的 HandlerMethodHandlerMethod handlerMethod = lookupHandlerMethod(request, getHandlerMethods());return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
这里的 lookupHandlerMethod() 方法根据请求 URL 查找已注册的处理方法,这些方法通常使用 @RequestMapping 注解。
3. HandlerAdapter
HandlerAdapter 负责调用处理器执行实际的业务逻辑。Spring MVC 通过 HandlerAdapter 将不同类型的处理器(如 Controller 接口实现类或注解控制器)适配成统一的调用方式。
RequestMappingHandlerAdapter 是最常用的 HandlerAdapter,其 handle() 方法如下:
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return invokeHandlerMethod(request, response, (HandlerMethod) handler);
}
invokeHandlerMethod() 方法负责调用实际的处理器方法,并生成 ModelAndView:
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {// 根据方法签名解析参数并调用处理方法ModelAndView mav = this.invokeAndHandle(webRequest, response, handlerMethod);return mav;
}
4. ViewResolver
ViewResolver 负责根据视图名解析实际的视图对象,通常是 JSP、Thymeleaf 等模板引擎生成的页面。Spring MVC 支持多种视图解析器,常见的是 InternalResourceViewResolver,它将逻辑视图名称解析为 JSP 文件路径。
InternalResourceViewResolver 的 resolveViewName() 方法:
@Override
protected View loadView(String viewName, Locale locale) throws Exception {// 根据视图名称解析 JSP 文件路径String url = getPrefix() + viewName + getSuffix();return new InternalResourceView(url);
}
5. ModelAndView
ModelAndView 是一个封装类,用于传递处理结果和视图信息。它包含模型数据和视图名称:
public class ModelAndView {private Object view;private Map<String, Object> model = new LinkedHashMap<>();
}
处理器方法执行后返回的 ModelAndView 对象会被 DispatcherServlet 传递给 ViewResolver 进行视图解析和渲染。
总结
Spring MVC 的核心流程通过 DispatcherServlet 调度请求,根据请求 URL 查找处理器,然后通过 HandlerAdapter 调用处理器执行业务逻辑,最终由 ViewResolver 解析视图并返回结果。这一系列的组件协作形成了强大的 Web 框架,既能支持注解驱动,也能扩展成多种视图技术。
可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。
相关文章:
面试官:讲一讲Spring MVC源码解析
好看的皮囊千篇一律、有趣的灵魂万里挑一 文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。…...
815. 公交路线(24.9.17)
题目 给你一个数组 routes,表示一系列公交线路。其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。例如,路线 routes[0][1,5,7] 表示第 0 辆公交车会一直按序列 1->5->7->1->5->7->1->... 这样的…...
Rust: Warp RESTful API 如何得到客户端IP?
在使用 Rust 的 Warp 框架来创建 RESTful API 时,如果你想要获取客户端的 IP 地址,通常需要在处理 HTTP 请求的函数中查看请求的头部或者底层连接的信息。不过,Warp 本身并不直接提供一个简便的 API 来直接获取客户端的 IP 地址,因…...
添加选择登录ssh终端
吼吼,这次成了一个小的瑞士军刀了 … … 一次性功能齐全,虽然只支持win10及以上...
【基于 Delphi 的人才管理系统】
基于 Delphi 的人才管理系统可以帮助企业或组织管理员工的信息,包括招聘、培训、绩效评估等方面。这种系统通常包括员工档案管理、职位发布、应聘者跟踪、培训计划安排等功能。下面是一个简化的人才管理系统设计方案及其代码示例。 系统设计概览 员工档案管理&…...
GetMaterialApp组件的用法
文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性 3. 示例代码4. 内容总结 我们在上一章回中介绍了"Get包简介"相关的内容,本章回中将介绍GetMaterialApp组件.闲话休提,让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经…...
ubuntu安装mysql 8.0忘记root初始密码,如何重新修改密码
1、停止mysql服务 $ service mysql stop 2、修改my.cnf文件 # 修改my.cnf文件,在文件新增 skip-grant-tables,在启动mysql时不启动grant-tables,授权表 $ sudo vim /etc/mysql/my.cnf [mysqld] skip-grant-tables 3、启动mysql服务 servic…...
Vue3项目开发——新闻发布管理系统(七)
文章目录 九、新闻分类管理模块设计开发1、新闻分类主页面设计2、封装页面组件3、改造页面4、新闻分类表格渲染4.1封装API,获取新闻分类数据4.2 表格动态渲染4.3表格增加 loading 效果5、实现新闻分类添加和编辑功能5.1 点击显示弹层5.2封装弹层组件 CateEdit5.3 准备弹层表单…...
ICMP
目录 1. 帧格式2. ICMPv4消息类型(Type = 0,Code = 0)回送应答 /(Type = 8,Code = 0)回送请求(Type = 3)目标不可达(Type = 5,Code = 1)重定向(Type = 11)ICMP超时(Type = 12)参数3. ICMPv6消息类型回见TCP/IP 对ICMP协议作介绍 ICMP(Internet Control Messag…...
Unity-Transform类-旋转
角度度相关 相对世界坐标角度 print(this.transform.eulerAngles); 相对父对象角度 print(this.transform.localEulerAngles); 注意:设置角度和设置位置一样 不能单独设置xyz 要一起设置 如果我们希望改变的 角度 是面板上显示的内容 那是改…...
如何使用 Vue 3 的 Composition API
Vue 3 引入了 Composition API,它提供了一种更灵活的方式来组织和重用逻辑。与 Vue 2 的 Options API 相比,Composition API 允许你将组件的逻辑按功能组织到函数中,而不是将它们分散到组件选项对象中。以下是如何在 Vue 3 中使用 Compositio…...
Mamba环境配置教程【自用】
1. 新建一个Conda虚拟环境 conda create -n mamba python3.102. 进入该环境 conda activate mamba3. 安装torch(建议2.3.1版本)以及相应的 torchvison、torchaudio 直接进入pytorch离线包下载网址,在里面寻找对应的pytorch以及torchvison、…...
2021 年 6 月青少年软编等考 C 语言二级真题解析
目录 T1. 数字放大思路分析 T2. 统一文件名思路分析 T3. 内部元素之和思路分析 T4. 整数排序思路分析 T5. 计算好数思路分析 T1. 数字放大 给定一个整数序列以及放大倍数 x x x,将序列中每个整数放大 x x x 倍后输出。 时间限制:1 s 内存限制&#x…...
2024网络安全、应用软件系统开发决赛技术文件
用软件系统开发技术方案 一、竞赛项目 2024 年全国电子信息行业第二届职工技能竞赛四川省应用 软件系统开发选拔赛分理论比赛和实际操作两个部分。理论比赛 成绩占30%,实际操作成绩占70%。 二、理论比赛 1、理论比赛范围 ①计算机系统基础知识: …...
CSP-J初赛每日题目2(答案)
二进制数 00100100和 00010100 的和是( )。 A.00101000 B.01100111 C.01000100 D.00111000 正确答案: D \color{green}{正确答案: D} 正确答案:D 解析: \color{red}{解析:} 解析: 00100100 36 \color{r…...
为什么Node.js不适合CPU密集型应用?
Node.js不适合CPU密集型应用的原因主要基于其设计理念和核心特性,具体可以归纳为以下几点: 单线程模型 Node.js采用单线程模型来处理用户请求和异步I/O操作。虽然这种模型在处理高并发I/O密集型任务时非常高效,因为它避免了传统多线程模型中的…...
数模原理精解【12】
文章目录 广义线性模型多元回归中的 R 2 R^2 R2(也称为决定系数)一、定义二、性质三、计算四、例子五、例题 偏相关系数一、定义二、计算三、性质四、例子 多元回归相关定义性质假设检验定义计算性质检验方法例子和例题例子例题例子 参考文献 广义线性模…...
steamdeck执行exe文件
命令行安装: sudo pacman xxxx //"xxxx"为软件名 ,或者搜索“arch linux 软件安装命令” 安装wine及wineZGUI 命令行输入: sudo pacman -S wine 后面需要输入密码,deck设置的用户密码即可(输入无反应是正…...
三、集合原理-3.2、HashMap(下)
3.2、HashMap(下) 3.2.2、单线程下的HashMap的工作原理(底层逻辑)是什么? 答: HashMap的源码位于Java的标准库中,你可以在java.util包中找到它。 以下是HashMap的简化源码示例,用于说明其实现逻辑&#…...
【激活函数】Activation Function——在卷积神经网络中的激活函数是一个什么样的角色??
【激活函数】Activation Function——在卷积神经网络中的激活函数是一个什么样的角色?? Activation Function——在卷积神经网络中的激活函数是一个什么样的角色?? 文章目录 【激活函数】Activation Function——在卷积神经网络中…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
