图解 Spring:HTTP 请求的处理流程与机制【4】
4. HTTP 请求在 Spring 框架中的处理流程
在穿越了 Web 容器和 Web 应用之后,HTTP 请求将被投送到 Spring 框架,我们继续剖析后续流程。Web 应用与 Spring MVC 的衔接是通过配置文件 mvc-servlet.xml 完成的,我们通过这份配置文件定义构成 Spring MVC 的各种核心组件和初始化配置,其中包括:控制器 Controller、视图解析器 ViewResolver、视图 View 等等。不同组件分别承担不同的功能,在介绍 Spring 框架处理 HTTP 请求流程之前,我们照例先了解一下这些核心组件。
4.1 Spring 框架核心组件简介
我们应用开发者在使用 Spring 时接触最多的就是各种注解,包括:@Component、@Controller、@Service、@Repository 等,这些都是 Spring 的核心组件。除此之外,我们还会使用 @RequestMapping、@RequestParam、@PathVariable、@RequestBody 等辅助性注解:
- 模型 Model:封装了业务数据,主要以 POJO 形式存在。
- 控制器 Controller:主要负责具体业务流程的调度控制,以及调用业务逻辑服务 Service。 控制器 Controller 处理完 HTTP 请求之后返回 ModelAndView 对象给前置分发器 DispatcherServlet,ModelAndView 中包含了模型 Model 对象和视图 View 名称。
- 视图 View:负责渲染呈现模型 Model 数据,以及提供表单供用户录入各种业务数据。
- 视图解析器 ViewResolver:负责根据已知的视图名称获取一个特定视图 View 子类实例对象。
- 处理器映射 HandlerMapping:主要负责控制器 Controller 的注册和查找,由应用上下文 ApplicationContext 持有。具体实现上它拥有 HashMap<String, Object> 类型的成员属性 handlerMap,其中 key 是 HTTP 请求的 URI 信息,value 可以是一个字符串或者处理请求的 HandlerExecutionChain。如果是 String,则视为 Spring Bean 名称。
- 服务 Service:主要负责实现具体的业务逻辑。
- 数据存储对象 Repository:也称为数据访问对象 DAO(Data Access Object),不管采用什么开发框架,大部分应用都需要跟数据库交互,DAO 就是将访问数据库操作做了封装,隔离了 SQL 相关复杂度。
抵达 Spring MVC 的所有 HTTP 请求均由前置分发器 DispatcherServlet 统一分发,在将请求分发给特定的控制器 Controller 之前需要借助处理器映射 HandlerMapping 来定位,大概过程如下:
- Web 容器监听主机特定端口,每当有请求抵达时,Web 容器最终将调用 Servlet 的 service 方法处理 HTTP 请求。在 Spring Web 应用中,接收 HTTP 请求的 Servlet 就是前置分发器 DispatcherServlet。
- 在前置分发器 DispatcherServlet 的 service 方法中判断 HTTP 请求类型,包括:GET、POST、PUT、PATCH 等等,然后再决定调用 doGet()、doPost()、doPut() 等方法。
- 在 doGet()、doPost()、doPut() 等方法中执行 processRequest() 方法,完成请求上下文的的初始化。
- 调用 doService() 方法,进一步执行 doDispatch() 方法。
- 在 doDispatch() 方法中获取 HTTP 请求的 mappedHandler 和 HandlerAdapter,然后再发起对业务控制器 Controller 的调用以及后续流程,等待处理结果再构建响应数据。
4.2 Spring 框架处理 HTTP 请求的流程
- 前置分发器 DispatcherServlet 接收到 HTTP 请求之后,将查找适当的控制器 Controller 来处理请求,它通过解析 HTTP 请求的 URL 获得 URI,再根据该 URI 从处理器映射 HandlerMapping 当中获得该请求对应的处理器 Handler 和处理器拦截器 HandlerInterceptor,最后以 HandlerExecutionChain 形式返回。
- 前置分发器 DispatcherServlet 根据获得的处理器 Handler 选择合适的适配器 HandlerAdapter。如果成功获得适配器 HandlerAdapter,在调用处理器 Handler 之前其拦截器的方法 preHandler() 优先执行。
- 方法 preHandler() 提取 HTTP 请求中的数据填充到处理器 Handler 的入参当中,然后开始调用处理器 Handler(即控制器 Controller)相关方法。
- 控制器 Controller 执行完成之后,向前置分发器 DispatcherServlet 返回一个模型与视图名对象 ModelAndView 。
- 前置分发器 DispatchServlet 根据模型与视图名对象 ModelAndView 选择适合的视图解析器 ViewResolver,前提该视图解析器必须已经注册至 Spring IOC 容器当中。
- 视图解析器 ViewResolver 将根据 ModelAndView 里面指定的视图名称获得特定的视图 View。
- 前置分发器 DispatchServlet 将模型数据填充进视图当中,然后将渲染结果返回给客户端。
在填充处理器 Handler 入参的过程中,Spring 还会根据配置做些预处理工作:
- HttpMessageConveter:将请求消息(JSON\XML 等格式数据)转换成 Java 对象。
- 数据转换:对 HTTP 请求中的数据做类型转换,例如:将 String 转换成 Integer、Double 等。
- 数据格式化:对HTTP 请求中的特定数据做格式化,例如将字符串转换成格式化数字或格式化日期等。
- 数据验证:验证数据的有效性(长度、格式等),验证结果存储到 BindingResult 或 Error 当中。
4.3 不同应用架构下 HTTP 请求处理流程的区别
Spring Web 应用架构经历了多个阶段的发展,最初主流的前端视图技术就是 JSP,在此基础上又演化出了三剑客框架 SSH(Struts\Spring\Hibernate),但这时候前后端其实还是耦合在一起的,不管是 JSP 还是 SSH,在前面 Spring 框架处理 HTTP 请求的流程中,必须要依赖视图解析器 ViewResolver 和视图 View。
从 Spring 诞生到现在已经15年多了,它关联的后端技术演化其实没有前端那么快,主要原因就是前端需求越来越丰富多样,前端视图层的开发工作量和复杂度不断增加。在这样的背景之下,越来越多的前端工程化解决方案涌现,其中最有成效的就是前后端分离,从 AngularJS\Backbone.js 到现在 React\Vue 等。在这种前后端分离架构下,前端就全部由静态资源(HTML\Javascript\CSS)等构成,可以独立部署在 Web 服务器当中,这样 Spring 框架就不需要再处理视图相关的内容,控制器 Controller 不再返回 ModelAndView,只需要反馈模型数据了。
本文主要价值是帮助大家梳理出端到端的全流程框架,也就是我们常说的全局视角或者上帝视角。有了这个框架之后,我们可以根据自己的需要按图索骥找相关节点的资料来研究学习,不至于陷入细节找不到方向。当然,考虑到我们每个人的工作学习情况不同,平时遇到的问题也不同,本文内容无法覆盖所有人遇到的问题,欢迎大家留言提问,也欢迎关注我的微信公众号“IT老兵哥”交流互动,我会尽力尽快解答大家提出的问题,谢谢!
本系列其他文章索引如下:
- 图解 Spring:HTTP 请求的处理流程与机制【1】
- 图解 Spring:HTTP 请求的处理流程与机制【2】
- 图解 Spring:HTTP 请求的处理流程与机制【3】
- 图解 Spring:HTTP 请求的处理流程与机制【5】
图解 Spring:HTTP 请求的处理流程与机制【4】的更多相关文章
- 图解 Spring:HTTP 请求的处理流程与机制【2】
2. HTTP 请求在 Web 容器中的处理流程 Web 容器以进程的方式在计算机上运行,我们知道进程是系统资源分配的最小单元,线程是系统任务执行的最小单元.从这个角度看,Web 容器就像是邮包收件人 ...
- 图解 Spring:HTTP 请求的处理流程与机制【1】
2003 年,老兵哥初到中兴开始研究生实习,Spring 就是那年诞生的,2004 年 3 月发布了 1.0 版本,到现在已经超过 15 年了.从单体式分层架构到云原生微服务架构,它稳坐在 JAVA ...
- 图解 Spring:HTTP 请求的处理流程与机制【3】
3. HTTP 请求在 Web 应用中的处理流程 在穿越了 Web 容器之后,HTTP 请求将被投送到 Web 应用,我们继续以 Tomcat 为例剖析后续流程.Web 容器与 Web 应用的衔接是通 ...
- 图解 Spring:HTTP 请求的处理流程与机制【5】
5. HTTP 请求处理相关配置文件说明 HTTP 请求穿越的整个空间是分层的,包括:Web 容器.Web 应用.Spring 框架等,它们每层都是通过配置文件配置初始化的,这是一种松耦合的架构设计. ...
- spring的set注入方式流程图解
spring的set注入方式流程图解 自己学习spring的一些笔记,详细画出了spring的set方式实现依赖注入的流程. 注意:<property name="UserDao&qu ...
- Spring Security 概念基础 验证流程
Spring Security 概念基础 验证流程 认证&授权 认证:确定是否为合法用户 授权:分配角色权限(分配角色,分配资源) 认证管理器(Authentication Manager) ...
- 描述Spring Web MVC的工作流程
Spring Web MVC的共工作流程如下: 1.浏览器发出Spring mvc请求,请求给前端控制器 DispatcherServlet处理. 2.控制器通过HandlerMapping维护的请求 ...
- Spring Security 的注册登录流程
Spring Security 的注册登录流程 数据库字段设计 主要数据库字段要有: 用户的 ID 用户名称 联系电话 登录密码(非明文) UserDTO对象 需要一个数据传输对象来将所有注册信息发送 ...
- 图解classloader加载class的流程及自定义ClassLoader
图解classloader加载class的流程及自定义ClassLoader 博客分类: JVM JavaJVM虚拟机EXTSUN /** * 转载请注明作者longdick http://l ...
随机推荐
- jQuery的原生替代
jQuery的原生替代,参考自你不需要jQuery,对其进行了更清晰的总结与分类,现代游览器基本都支持(ie10+以上),只整理了最简洁实用的原生代码,过分累赘的实现没有加入 元素获取 jQuery ...
- 《ECMAScript6入门》笔记
let和const命令 let命令 循环体的let变量只对花括号作用域可见,花括号外不可见 循环体的语句部分是一个父作用域,而循环体内部是一个单独的子作用域 let声明的变量不存在变量提升,未声明的使 ...
- 变量 + 数据类型(数字 + 字符串)(day03整理)
目录 一.上节课回顾 四 编程语言分类 (一) 机器语言 (二)汇编语言 (三) 高级语言 (四) 网络瓶颈效应 五.执行python程序两种方式 (一) 交互式(jupytre) (二) 命令行式( ...
- Java11新特性 - Epsilon GC和ZGC
Java11中新增了两个GC,Epsilon GC和ZGC. Epsilon垃圾收集器 A NoOp Garbage Collector 没有操作的垃圾收集器 JDK上对这个特性的描述是:开发一个处理 ...
- Chrome插件开发(二)
作为一个前端开发者,我们经常需要和各种各样的接口打交道,很多时候我们的开发环境的域和接口所在的域是不同的,比如我们本地开发环境运行域是localhost,但接口所在的域是www.xx.com,这个时候 ...
- Android自定义控件:图形报表的实现(折线图、曲线图、动态曲线图)(View与SurfaceView分别实现图表控件)
图形报表很常用,因为展示数据比较直观,常见的形式有很多,如:折线图.柱形图.饼图.雷达图.股票图.还有一些3D效果的图表等. Android中也有不少第三方图表库,但是很难兼容各种各样的需求. 如果第 ...
- 【C#多线程】2.线程池简述+两种传统的异步模式
线程池简述+两种传统的异步编程模式 1.线程池简述 首先我们要明确一点,编程中讲的线程与平时我们形容CPU几核几线程中的线程是不一样的,CPU线程是指逻辑处理器,比如4核8线程,讲的是这个cpu有8个 ...
- 在虚拟机上的关于FTP FTP访问模式(虚拟用户模式)
首先你要有vsftpd服务 可以先去yum中下载(当然你要有本地yum仓库) 输入命令: yum install vsftpd 下载完成之后打开vsftpd服务 输入命令:systemctl ...
- 学习笔记49_Redis
Redis和memcache区别: 1 . mm是通过客户端驱动实现集群化,Redis是通过服务器配置文件集群 2. redis是可以进行持久化的存储 3. redis提供高级的数据结构,队列,栈都提 ...
- 分手是祝愿:dp
Description Zeit und Raum trennen dich und mich. 时空将你我分开. B 君在玩一个游戏,这个游戏n个灯和n个开关组成,给定这n个灯的初始状态,下标为从1 ...