SpringMVC原理及流程解析
前言
春节期间宅在家里闲来无事,对SpringMVC进行了比较深入的了解,将之前模糊不清的地方基本摸索清楚了,特此撰文总结记录一下。
正文
一、一个请求为什么会调用到SpringMVC框架里?
首先问大家一个问题,为什么一个请求能进入SpringMVC的框架代码里?
答案就是Servlet。Web容器在启动的时候会对Servlet进行初始化,对应到SpringMVC中就是将DispatcherServlet初始化,而当请求到来的时候,Web容器(如tomcat)会调用servlet的doService方法,从而进入DIspatcherServlet的处理逻辑。
所以,SpringMVC这个轻量级Web框架,本质上是对Servlet的封装。在其中封装了大量的便捷功能,让我们可以不用操作冗长的Servlet代码,就能便捷的开发。
二、SpringMVC框架处理的流程
流程图网上有很多,此处我就随便找一个粘贴过来了... 下面看图说话

请求过来之后调用Servlet的doService方法,此方法在DispatcherServlet中进行了实现,处理核心逻辑的方法是doDispatch()方法。
2中是先进入处理器映射器-HandlerMapping中,获取对应的HandlerExecutionChain。HandlerMapping是什么?这要从springmvc注入Controller的方式说起,有两种,分别为:在类上加@Controller注解,这也是我们最常用的;还有一种是实现Controller接口或HttpRequestHandler接口。这两种对应不同的MappingHandler,分别为:RequestMappingHandlerMapping、BeanNameUrlHandlerMapping。所以第二步就是分别调一下这两个handlerMapping,看看哪个能匹配到处理请求的MethodHandler,能匹配到就将MethodHandler封装成HandlerExecutionChain返回。
3是匹配处理器适配,从2中拿到MethodHandler执行体之后,在3中匹配对应的HandlerAdapter。此处用了策略的设计模式,HandlerAdapter接口中的support方法负责判断是否是由当前扩展类处理,handle方法对当前请求进行处理。有三个实现类,分别为RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter。默认是RequestMappingHandlerAdapter。
4是得到处理器适配器后,调用其handle方法将请求转到对具体目标方法的调用。不同的实现类在调用handle方法时用不同的方式组装方法参数、调用方法。比如RequestMappingHandlerAdapter的handle方法通过反射调用到目标方法,而实现Controller接口的会直接调用接口方法。调用完之后得到ModelAndView。
5是通过ViewResolver对ModelAndView进行解析,得到视图后给前端渲染。
所以看下来,SpringMVC的重点其实就是2/3/4这三步。
三、SpringMVC框架的扩展点
首先HandlerMapping可以扩展,实现接口并放入handlerMappings集合中即可。但是这需要对现有框架做较大改动,因为Controller中的方法也要放入这个HandlerMapping实现类中,所以一般只有框架作者才会做此类扩展。
其次HandlerAdapter可以扩展,同样实现接口并放入handlerAdapters集合中即可。
最后通过实现接口 org.springframework.web.servlet.config.annotation.WebMvcConfigurer重写其中的方法,往里添加ViewResolver、ArgumentResolver等类来实现对视图的解析、对参数的解析。
通过上面可以看到,一个好的框架是如何通过面向接口编程来预留扩展点的。
四、总结
一个好的框架,核心思路以及流程可能并不复杂,但是当尽可能多的增加上扩展点、填充上针对各种场景的处理逻辑后,就会显得整体繁杂,使得新人刚看一个框架源码是不明就里,而当你能透过这繁杂的表象看清其精简的核心时,你也就理解了设计者的思想。
本文主要给自己查漏补缺用,写的深一脚浅一脚,如有有异议的地方还请指正!
SpringMVC原理及流程解析的更多相关文章
- [SpringMVC]SpringMVC学习笔记一: springmvc原理及实例解析.
前言:今天来回顾下SpringMVC的开发原理, 使用图文并茂的方式 来解析其中的内幕, 我相信懂了其中的运行机制后, 对于面试中SpringMVC大家都可以说so easy了. 一, 图示法 第二张 ...
- SpringMVC 原理和流程
请求到来时,第一个接受这个请求的前端控制器叫DispatcherServlet(这个需要在web.xml中配置),后端控制器叫Controller. 简化版流程: 1.spring mvc将所有的请求 ...
- SpringMVC的应用与工作流程解析
一:SpringMVC是什么 SpringMVC只是Spring的一个子框架,作用学过Struts2的应该很好理解,他们都是MVC的框架.学他就是用来代替Struts2的,那么为什么不用Struts2 ...
- DNS解析原理和流程
DNS解析原理和流程 DNS解析其实就是将IP地址(202.96.134.133)变成域名(www.xxxxx.com) 网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址的,所 ...
- 《面试经典系列》- SpringMVC原理及工作流程
前言 SpringMVC 作为 MVC 的开源框架,现在依旧是不少项目使用的重点框架.SpringMVC = Struts2 + Spring,SpringMVC就相当于 Struts2 + Spri ...
- Java开发学习(二十三)----SpringMVC入门案例、工作流程解析及设置bean加载控制
一.SpringMVC概述 SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装.SpringMVC是处于Web层的框架,所以其主要的作用就是用来 ...
- SpringMVC之处理流程
之前在学servlet时写过JavaWeb与Asp.net工作原理比较分析,那篇主要是大致描述了下servlet的工作流程,今天在家了解了下springmvc的工作原理,与asp.net中的mvc进行 ...
- SpringMVC 原理 - 设计原理、启动过程、请求处理详细解读
SpringMVC 原理 - 设计原理.启动过程.请求处理详细解读 目录 一. 设计原理 二. 启动过程 三. 请求处理 一. 设计原理 Servlet 规范 SpringMVC 是基于 Servle ...
- SSL/TLS算法流程解析
SSL/TLS 早已不是陌生的词汇,然而其原理及细则却不是太容易记住.本文将试图通过一些简单图示呈现其流程原理,希望读者有所收获. 一.相关版本 Version Source Description ...
随机推荐
- redis集群在线迁移
地址规划 主机名 ip地 端口 redis01 10.0.0.10 6379.6380 redis02 10.0.0.60 6379.6380 redis03 10.0.0.61 6379.6380 ...
- 记一次NoHttpResponseException问题排查
上传文件程序会有一定的概率提示错误,错误率大概在1%以下,错误信息是:org.apache.http.NoHttpResponseException , s3-us-west-1.amazonaws. ...
- 01 MATLAB基本概念
基本概念 整数类型 相同整数类型相乘还是整数 整数与浮点数相乘是这种整数类型 不同整数类型不能相乘,除非强制类型转换 整数与整数相乘: >> x = uint32(120); >&g ...
- 深入理解 Python 中的装饰器
装饰器本质上也是函数,接收函数对象来作为参数,并在装饰器的内部来调用接受的函数对象完成相关的函数调用,也可以这样理解 ,为了方便在几个不同函数调用之前或者完成相关的统一操作,注意是完成统一的操作, ...
- 在centos7中安装MySQL5.7
1.下载mysql源安装包 wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 2.安装mysql源 yu ...
- Pytorch 分割模型构建和训练【直播】2019 年县域农业大脑AI挑战赛---(四)模型构建和网络训练
对于分割网络,如果当成一个黑箱就是:输入一个3x1024x1024 输出4x1024x1024. 我没有使用二分类,直接使用了四分类. 分类网络使用了SegNet,没有加载预训练模型,参数也是默认初始 ...
- 新闻网大数据实时分析可视化系统项目——6、HBase分布式集群部署与设计
HBase是一个高可靠.高性能.面向列.可伸缩的分布式存储系统,利用Hbase技术可在廉价PC Server上搭建 大规模结构化存储集群. HBase 是Google Bigtable 的开源实现,与 ...
- 一个Java的小问题
老师今天在讨论群里抛出了一个问题,让大家尝试思考一下他所给的一段代码输出是什么. 其代码如下: class T { void foo() { this.bar(); } void bar() { Sy ...
- oracle练习-day03
.创建表空间.创建用户赋权限.创建表语法:.常见的数据类型字符 myname ) varchar2:推荐使用这个 可变长度最大字符 myname varchar2() 字 ...
- Metasploit学习笔记——强大的Meterpreter
1. Meterpreter命令详解 1.1基本命令 使用Adobe阅读器渗透攻击实战案例打开的Meterpreter会话实验,靶机是WinXP.由于所有命令与书中显示一致,截图将书中命令记录下来. ...