摘要:听到这个问题我心里一紧,嘴上在笑,脑子飞速地回想当年背过的知识点:“视图解析器...拦截器...处理器映射...诶,不对,得讲顺啊!”
开场白:来自面试官的一击灵魂拷问
说出来你可能不信,我在社招面试的第一轮、第二轮、第三轮,都被问到了这道题:
“你能详细说说 Spring MVC 的工作原理吗?DispatcherServlet 在其中起什么作用?”听到这个问题我心里一紧,嘴上在笑,脑子飞速地回想当年背过的知识点:“视图解析器...拦截器...处理器映射...诶,不对,得讲顺啊!”
这题乍一看不难,但想答得“条理清晰 + 术语准确 + 带点源码味道”,真不容易。
所以我决定把这篇文章写出来,给正在准备面试的你打打气、补补刀。
先讲一个小故事:我们为什么需要 Spring MVC?
设想你是个餐厅老板。客户点菜 -> 厨房做菜 -> 上菜 -> 客户吃饭。
这个流程是不是很像我们平时写 Web 应用的处理流程?
用户在浏览器发出请求(点菜);
系统需要有人接单并决定谁来做菜(控制器);
根据客户点的菜找到做这道菜的厨师(处理器映射);
做好之后上菜(返回视图);
吃完之后结账走人(返回响应);
而这个“整个点菜 - 做菜 - 上菜”的流程管理者,就是我们今天的主角——DispatcherServlet,也就是 Spring MVC 的调度中心。
正菜来啦:Spring MVC 的整体工作流程
下面是最最核心的一句话总结:
Spring MVC 是基于前端控制器(Front Controller)设计模式的 Web 框架,它的核心就是 DispatcherServlet,它把请求分发给真正的处理者(Controller),再将结果返回给用户。整个流程分为七步(强烈建议你能画图!):
1. 用户发起请求(比如访问 /user/list)
用户在浏览器输入一个地址,例如:
这个请求先被 Web 容器(Tomcat)接收,再被转交给 Spring MVC 的核心组件——DispatcherServlet。
2. DispatcherServlet 拿到请求,第一件事:找 HandlerMapping
DispatcherServlet 的第一步,是找谁来处理这个请求。
它会遍历所有的 HandlerMapping,比如:
RequestMappingHandlerMapping
BeanNameUrlHandlerMapping
你自定义的 HandlerMapping...
找出一个与请求匹配的处理器(Handler),也就是我们平时写的那个 @Controller + @RequestMapping 的方法。
这时候,它还会找出与之绑定的 HandlerAdapter(适配器),方便后续执行。
3. DispatcherServlet 调用 HandlerAdapter 执行控制器方法
拿到处理器(Controller 方法)后,并不是 DispatcherServlet 亲自去调的。
而是通过 HandlerAdapter 去执行它。这样做的好处是:可以适配不同类型的处理器(比如普通 Controller、注解式 Controller、HttpRequestHandler等)
执行控制器方法时,会用上各种参数解析器(ArgumentResolvers)帮你自动注入:
@RequestParam
@PathVariable
HttpServletRequest
Model、Map...
4. Controller 方法执行完毕,返回一个 ModelAndView
这是 Controller 层的出口。
比如你写了:
返回的 ModelAndView 里有两个东西:
View Name(视图名,如 "userList")
Model 数据(比如 users)
5. DispatcherServlet 把视图名交给 ViewResolver 找真正的 View
“userList” 到底是哪一个页面?HTML?JSP?Thymeleaf?还是 PDF?
这时候,就要靠ViewResolver来解析了!
Spring 提供了很多 ViewResolver 的实现:
InternalResourceViewResolver:用于 JSP
ThymeleafViewResolver:用于 Thymeleaf
你也可以自定义视图解析器
ViewResolver 根据名字找到了真正的 View 对象,然后交还给 DispatcherServlet。
6. DispatcherServlet 渲染视图(View.render)
接下来就是 DispatcherServlet 和 View 的合作时刻了!
DispatcherServlet 把之前从 Controller 那里得到的 Model 数据传给 View,View 会将它“渲染”为 HTML 页面。
这一步,页面模板技术(JSP / Thymeleaf / Freemarker)发挥了关键作用!
7. 最后一步:响应返回给浏览器
渲染出来的 HTML 会被写入 HttpServletResponse,返回给客户端。
用户在浏览器看到页面啦!
总结一下:Spring MVC 的工作流程
一图胜千言,文字版总结如下:
是不是一整个前后端协同、模块解耦、职责清晰的系统设计呢?这就是 Spring MVC 牛的地方!
专门讲讲 DispatcherServlet 的“调度之道”
好啦,咱们前面把整体流程理了一遍,下面来重点看看面试官特别关心的 DispatcherServlet。
DispatcherServlet 本质上是一个 Servlet,它继承了 HttpServlet,但是又通过 doDispatch 方法完成了整个 MVC 流程的调度。
DispatcherServlet 的职责列表
初始化所有 MVC 组件(在容器启动时):
HandlerMapping
HandlerAdapter
ViewResolver
异常处理器(HandlerExceptionResolver)
MultipartResolver(处理上传)
LocaleResolver(多语言)
ThemeResolver(主题)
接收请求,执行 doDispatch 方法;
找处理器(Controller 方法);
调用处理器;
找视图;
渲染视图;
异常处理;
是不是一个超级“全能选手”?
DispatcherServlet 的源码探秘(轻量版)
你要是想进一步 impress 面试官,可以提到它的源码中的 doDispatch 方法:
是不是感觉它就像一个调度中心,把各个模块串联起来、执行流程控制、处理异常,是整个 Spring MVC 的“心脏”。
面试加分Tips:如何把这道题答得更“香”?
如果你想让面试官眼前一亮,可以:
先用一句话讲清楚:“Spring MVC 是典型的前端控制器模式,DispatcherServlet 是请求分发的核心”;
然后讲清楚七步流程;
再补充 DispatcherServlet 的职责、常见组件、源码入口;
最后加上一两点拓展,比如拦截器、国际化、异常处理等;
比如这样答:
“Spring MVC 的核心是 DispatcherServlet,它作为前端控制器,负责将用户请求分发到具体的 Controller 方法。整个流程包括请求接收、处理器查找、方法执行、视图解析和页面渲染,形成一个高内聚低耦合的处理链。而 DispatcherServlet 是整个链条的调度中心,贯穿了请求的始末。”是不是既专业又完整?
小米的碎碎念:理解比背诵重要
我以前背过各种 MVC 步骤,流程图都画过好几版,但一到面试就卡壳。
后来我把 DispatcherServlet 比作餐厅里的“大堂经理”,理解了每一步的角色和职责,才真正明白了它是如何调度整个流程的。
所以你不要死记硬背,而是去理解“它为什么这么设计”“各个模块如何协作”。
彩蛋结尾:反问面试官的一句话
最后分享一个我在面试时反问面试官的小技巧:
“我对 Spring MVC 的 DispatcherServlet 比较熟悉,请问你们在实际项目中有没有做过定制?比如扩展 HandlerAdapter 或 ViewResolver?”这句话既展示了你对原理的掌握,又体现了你思考落地应用的能力,真的很加分!
最后一口饭:记住这三句话!
DispatcherServlet 是 Spring MVC 的核心调度器,负责请求的分发与响应的输出;
MVC 的每一步(Mapping、Adapter、View、Render)都解耦且可扩展;
理解架构设计思路,比背套路题更重要!
我是一名31岁还在码字的程序员大哥哥,爱技术爱分享,社招转型刚上岸。如果你觉得这篇文章对你有用,点个“在看”或转发给正在准备面试的朋友吧!
来源:DLA点线圈科技