2003 年,老兵哥初到中兴开始研究生实习,Spring 就是那年诞生的,2004 年 3 月发布了 1.0 版本,到现在已经超过 15 年了。从单体式分层架构到云原生微服务架构,它稳坐在 JAVA 应用框架的头把交椅上从未被撼动,它给我们带来了巨大的价值,不仅可以降低开发难度,同时还可以提升开发效率。但时间这把杀猪刀不仅改变了老兵哥,也同样没放过 Spring,我们都变得越来越强大了。
在 Spring Boot / Spring Cloud 面世之前,它已经演进了 5 个大版本和无数小版本,功能和生态都变得越来越丰富。但对初涉 Spring 的小伙伴们来说,这就不太公平了,不像老兵哥可以伴着它慢慢成长,现在这套技术栈已经很庞大了,短时间内吃透这个巨无霸,有没有捷径可走呢?有,就像当年 DOS 操作系统一张软盘就装下了,总共才几 MB,现在动不动就几十上百 GB,但操作系统内核是很小的,其原理机制就是教科书上那些,一生二、二生三、三生万物,唯有掌握这些稳定不变的“一二三”,即核心原理机制(例如:IOC \ AOP \ ORM 等),那我们的学习就可以达到事半功倍了。
就像我们购买了毛坯房,入住前必须装修一番,其中水、电、气、网等管路的布线必须先行,不同管路有不同的走法,有的走地板,有的走墙面,等管路都铺设妥当了才能铺地砖、吊天花、刷墙贴纸等。作为业主,如果你不知道这些管路的走线,当出现停电、断网或漏水等问题时,你压根不知道怎么分析、定位和修复。在公司内老兵哥经常接到的问题求助,由于小伙伴不知道这些原理机制,蛮简单的问题分析定位了好些天还没头绪。如果循着原理机制,那我们就可以做到游刃有余了。
其实,这些底层原理机制并不算复杂,仅仅是我们不知道,或者缺乏好资料,老兵哥准备通过图解的方式把这些原理机制剖析给大家伙听。本系列文章将聚焦 Spring 处理 HTTP 请求的全流程,帮助大家了解掌握 Spring 这座摩天大楼里面的管路布线,让学习变得事半功倍,让使用变得游刃有余,具体将包含下述几个方面内容:
- HTTP 请求处理全流程,包括浏览器、Web 服务器、应用 Spring 等;
- Web 服务器与应用 Spring 之间的交互界面、协作机制和配置规则等;
- Spring 处理 HTTP 请求的机制,包括 Dispatcher、Controller、View、Model、Service、DAO 等;
- 不同应用架构场景下 HTTP 请求处理的子流程,包括 JSP、前后端分离等;
- HTTP 请求处理相关配置文件说明,包括 Web、Bootstrap、Spring MVC、Application Context 等;
- HTTP 请求处理常见问题说明等。
适合读者:开发、测试、架构等
1. HTTP 请求处理流程概览
由计算机构建起来的网络空间是一个虚拟的世界,它是我们人类脑力的延伸。虽然虚拟世界既抽象又幻化,但它终究是根据我们建设物理世界的经验构建出来的。混迹 IT 江湖的时间也不短了,老兵哥我找到了一种理解虚拟世界的方法,就是在现实世界找到原型,原型更加形象生动,我们对它也非常熟悉,通过原型就能更加准确地了解计算机技术背后的机制原理。客户端(或浏览器)、Web 容器、Web 应用、Spring 框架等处理 HTTP 请求的过程,我们可以用现实世界中的什么原型来跟它对应呢?我们可以将其类比为物流快递投送文件包裹的过程。
计算机网络就像现实世界的交通路网,四通八达的网络主要职责就是承载货物的运输。在 OSI 七层或 TCP/IP 四层网络协议模型中,HTTP (Hyper Text Transfer Protocol)和 FTP(File Transfer Protocol)、SMTP(Simple Mail Transfer Protocol)、POP3(Post Office Protocol 3)、IMAP4(Internet Mail Access Protocol)等协议都隶属于应用层协议,这些协议就好比运送不同类型货物的物流快递公司,FTP 这套体系是专门运送文件的,SMTP、POP3、IMAP4 是专门投递邮件的,而 HTTP 协议最初是用于超文本的。但随着万维网(WWW)的蓬勃发展,HTTP 这套协议体系得到了最为广泛的发展,它的设计非常优良,带来了灵活性、扩展性和易用性,可以承载各种类型信息的传输,就像现在互联网物流公司越做越大,可以覆盖越来越多的业务了。
HTTP 请求或应答就像一个邮包,这个邮包分成报文头和报文体,其中报文体就是被承运的信息载荷,而报文头就像我们平时邮寄东西时填写的快递单,包括收(发)件人地址、服务等级要求、邮寄物品描述等。针对本文的主题,我们就只重点剖析一下收件人地址。一个符合 RESTful 风格的服务接口 API 的 HTTP URL 如下所示:
http:// {ip} : {port} / {context-path} / {service-name} / {method-name}
举个具体的例子,就像我们要往下面这个地址投递一份文件来完成用户注册:
http://201.187.10.21:8080/spring-demo/user/register
上述格式是供我们阅读的,最终这些信息要填写至 HTTP 报文当中,真实效果如下所示:
POST /spring-demo/user/register HTTP/1.1
Accept: application/json
Accept-Language: zh-cn
User-Agent: Mozilla/5.0
Host: 201.187.10.21:8080
Content-Length: 112
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=12DII6898EFY998APBE17Bname=itlaobingge&password=123456&sex=male&age=30
接下来,我们一起逐段解析一下这个 HTTP URL,看看每段信息存在的意义:
- ip:IP 地址信息,用于特定网络中不同计算机的寻址。
- port:端口信息,用于同一台计算机上不同 Web 容器的寻址,一台计算机可以运行多个 Web 容器实例。
- context-path:上下文路径,用于同个 Web 容器内不同应用的寻址,一个 Web 容器实例可以部署多款应用。
- service-name:服务名称,用于同个应用内部不同服务的寻址,一个应用内部通常会有多个服务。
- method-name:方法名称,用于同个服务内部不同方法的寻址,一个服务通常都会包含多个方法。
上述收件人地址是由客户端(或浏览器)填写的,HTTP 传输体系将根据收件人地址信息对邮包进行投送,基于 IP 地址或域名信息找到了特定的计算机,而计算机会根据端口信息将邮包交给具体的 Web 容器实例。接下来,Web 容器会接管邮包投送任务,它将根据上下文路径找到具体的应用。如果当前这款应用是采用 Spring 框架构建的,那么Spring 将接管邮包投送任务,它将根据服务名称和方法名称找到真正可以处理邮包当中载荷信息的服务方法。该服务方法会及时处理邮包内的信息,待处理完成后再将结果信息装进新的邮包快,递回客户端(或浏览器)。
如下图所示,这就是 HTTP 请求穿越网络、计算机、Web 容器、Web 应用、Spring 框架的过程示意。
本文主要价值是帮助大家梳理出端到端的全流程框架,也就是我们常说的全局视角或者上帝视角。有了这个框架之后,我们可以根据自己的需要按图索骥找相关节点的资料来研究学习,不至于陷入细节找不到方向。当然,考虑到我们每个人的工作学习情况不同,平时遇到的问题也不同,本文内容无法覆盖所有人遇到的问题,欢迎大家留言提问。
今天先分享到这里,如果你觉得有价值,麻烦动动手指 转发 给其他需要的小伙伴。另外,老兵哥我后续还会分享职业规划、应聘面试、技能提升、影响力打造等经验,欢迎 关注 本博客或歪信公众号「 IT老兵哥 」!
本系列其他文章索引如下:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。