手写tomcat(2):Servlet原理和自定义tomcat

作为 Java 后端开发,我们每天都在用 Tomcat,但你真的懂它和 Servlet 的底层逻辑吗?今天就从Servlet 的继承关系Tomcat 的请求流程 ,讲到如何手写一个简易 Tomcat,彻底搞懂 Web 容器的核心原理。

一、Servlet原理

Servlet 是 Java EE 定义的Web 组件接口,负责处理 HTTP 请求、生成响应。但直接用 Servlet 接口太麻烦,所以 Java EE 提供了 "接口 - 抽象类 - 实现类" 的简化体系:

1.1Servlet 的继承关系(核心分层)

Servlet 接口:定义了 Servlet 的生命周期方法(5 个核心方法):

java 复制代码
// Servlet接口的核心方法
init()          // 初始化:创建Servlet对象
getServletConfig() // 获取配置信息
service()       // 处理请求(核心)
getServletInfo() // 获取运行信息
destroy()       // 销毁对象

GenericServlet 抽象类 :帮我们实现了 Servlet 接口中除service()外的所有方法,减少重复代码。

HttpServlet 抽象类 :在 GenericServlet 基础上,把service()方法拆分成了 HTTP 请求对应的方法(doGet()doPost()等),适配 HTTP 协议。

自定义 Servlet 类 :我们实际开发时,只需要继承 HttpServlet,重写doGet()/doPost()即可。

二、Tomcat 是怎么工作的?请求从发起到响应的全流程

当你在浏览器输入http://ip:8080/xxx/my,Tomcat 到底做了哪些事?

2.1.Tomcat 请求处理流程(核心步骤)

1.网络通信层:Socket+ BIO/NIO

(1)Tomcat 通过网卡监听端口(比如 8080),用 Socket 建立客户端与服务器的连接;

(2)早期 Tomcat用BIO(阻塞 IO):一个请求占一个线程,效率低;后来升级为 NIO/AIO(非阻塞 IO)优化性能。

2.请求解析层:拆 HTTP 报文

(1)通过InputStream读取请求数据,解析出请求地址、请求类型(GET/POST)、Cookie等信息。

3.Servlet 容器:匹配对应的 Servlet

(1)Tomcat 内部维护了一个HashMap 容器 (Servlet 容器),key是 Servlet 的访问路径(比如/my),value是对应的 Servlet 对象;

(2)用解析出的请求地址作为key,找到对应的 Servlet 对象(比如MyServlet)。

4.调用 Servlet 处理请求

(1)根据请求类型(GET/POST),调用 Servlet 的doGet()/doPost()方法,处理业务逻辑并生成响应。

5.返回响应:通过 OutputStream 写回数据

(1)把响应结果通过OutputStream写回客户端,完成请求流程。

三、动手写一个简易 Tomcat:核心逻辑拆解

明白了 Tomcat 的原理,我们可以自己实现一个极简版 Web 容器,核心只需要 4 步:

步骤 1:启动时初始化 Servlet 容器

Tomcat 启动时,会扫描项目中的 Servlet 并初始化容器:

  1. 扫描 Servlet 类:遍历项目文件夹,获取所有 Servlet 类的全路径名;
  2. 解析 @WebServlet 注解 :读取注解中的访问路径(比如@WebServlet("/my"));
  3. 生成 Servlet 容器:用 HashMap 存储 "访问路径 → Servlet 对象" 的映射(通过反射创建 Servlet 对象)。

步骤 2:监听端口,接收请求

用 Socket 监听指定端口(比如 8080),等待客户端连接:

java 复制代码
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept(); // 阻塞等待请求

步骤 3:解析请求,封装 Request 对象

读取 Socket 的输入流,解析 HTTP 请求的路径、请求类型、参数 等信息,封装成自定义的HttpServletRequest对象。

步骤 4:匹配 Servlet / 静态资源,处理请求

  1. 匹配 Servlet :用请求路径从 HashMap 容器中找对应的 Servlet 对象,调用对应的doGet()/doPost()方法;
  2. 处理静态资源:如果请求的是 HTML/CSS/JS 等静态资源,直接读取文件并返回;
  3. 404 处理:既不是 Servlet 也不是静态资源时,返回 404 错误。

步骤 5:封装 Response,返回结果

把处理后的响应数据封装成HttpServletResponse对象,通过 Socket 的输出流写回客户端。

四、总结:Web 容器的核心本质

不管是 Tomcat 还是我们手写的简易容器,核心逻辑都是:

网络通信:用 Socket 实现客户端 - 服务器的连接;

请求解析:拆分 HTTP 报文,提取关键信息;

Servlet 管理:用容器(HashMap)管理 Servlet,实现 "路径→组件" 的映射;

请求分发:根据请求信息调用对应的组件(Servlet / 静态资源),生成响应。

相关推荐
2501_9167665410 小时前
【面试题1】128陷阱、==和equals的区别
java·开发语言
a程序小傲11 小时前
蚂蚁Java面试被问:注解的工作原理及如何自定义注解
java·开发语言·python·面试
幽络源小助理11 小时前
SpringBoot+Vue摄影师分享社区源码 – Java项目免费下载 | 幽络源
java·vue.js·spring boot
0和1的舞者11 小时前
《软件测试分类指南:8 大维度 + 核心要点梳理》
java·软件测试·单元测试·测试·黑盒测试·白盒测试·测试分类
TAEHENGV11 小时前
创建目标模块 Cordova 与 OpenHarmony 混合开发实战
android·java·开发语言
是一个Bug11 小时前
如何阅读JDK源码?
java·开发语言
Ledison712 小时前
Springboot 3.5.7 + Springcloud 2025 升级记录
java
没有bug.的程序员12 小时前
熔断、降级、限流:高可用架构的三道防线
java·网络·jvm·微服务·架构·熔断·服务注册
派大鑫wink12 小时前
【Day15】集合框架(三):Map 接口(HashMap 底层原理 + 实战)
java·开发语言
派大鑫wink12 小时前
【Day14】集合框架(二):Set 接口(HashSet、TreeSet)去重与排序
java·开发语言