手写Tomcat原理整理
一、启动阶段Tomcat 启动的时候主要做一件事把所有的 Servlet 找出来实例化然后存到容器里。具体分为六个步骤第1步扫描目录Tomcat 启动后首先会扫描 webapp 目录下的所有子目录和子文件把里面所有的 .class 文件都筛选出来。第2步获取全类名拿到每个 .class 文件后获取它的全路径名也就是包名加类名比如 com.example.MyServlet。第3步反射加载拿到全类名之后调用 Class.forName(全类名) 这个方法。这里用的是反射机制。为什么要用反射而不是直接 new 呢因为 Tomcat 的开发者在写框架的时候根本不知道使用者将来会写什么 Servlet类名叫什么在哪个包里。new 的前提是编译时必须知道类名所以这里只能通过反射在运行时动态加载类。第4步注解筛选拿到所有 Class 对象之后遍历每一个 Class 对象检查它上面有没有 WebServlet 注解。带这个注解的类才是我们要管理的 Servlet。注解里面还包含了 Servlet 的访问路径比如 WebServlet(/login)。第5步创建实例对筛选出来的 Servlet 类调用 newInstance() 方法创建实例。newInstance() 和 new 的区别在于new 是编译时确定类名而 newInstance() 是运行时通过 Class 对象动态创建它只能调用无参构造器。第6步构建容器实例创建好之后再通过反射获取这个 Servlet 类里的 doGet 和 doPost 方法对象Method。然后我们构建两个 HashMap第一个存 Servlet 实例key 是 WebServlet 注解里的路径value 是 Servlet 实例对象第二个存方法key 同样是路径value 是 doGet 或 doPost 的 Method 对象这样启动阶段就完成了。总结一下就是扫目录 → 筛类文件 → 反射加载 → 注解筛选 → 实例化 → 存 HashMap。二、请求处理阶段启动完成之后Tomcat 就进入运行状态开始接收和处理 HTTP 请求。整个处理流程也是八个步骤第1步Socket 监听端口Tomcat 通过 Socket 监听 8080 端口。这里要注意源码中的 Socket 不是 Java 标准库的普通 Socket而是用了 Netty 框架的 Socket因为 Netty 性能更高支持异步事件驱动。第2步请求放入线程池队列当一个 HTTP 请求到来时Tomcat 不会立即创建新线程来处理而是先把这个请求放到线程池的任务队列里。为什么要这么做呢有两个原因第一防止内存耗尽。 如果瞬间来上千个请求每个请求都开一个新线程每个 Java 线程默认栈空间是 1MB1000 个线程就是 1GB 内存很容易 OOM 导致服务器死机。线程池有最大线程数限制超出的请求在队列里等着队列满了还有饱和策略直接拒绝保护服务器不宕机。第二减少线程创建销毁的开销。 线程的创建和销毁调用的是操作系统的本地方法涉及栈空间的申请和回收这个开销是毫秒级的。高并发场景下频繁创建销毁线程的开销会非常大。线程池里的线程在 run() 方法里有一个死循环会不断从队列里取任务线程不会销毁实现了线程复用。第3步线程池分配线程处理线程池里的空闲线程会从任务队列中取出一个请求来处理。第4步封装 Request 和 Response 对象线程拿到请求后首先把通过端口传过来的 HTTP 字符流进行解析封装成 HttpRequest 对象和 HttpResponse 对象。同时从 URL 中提取出请求路径去掉 IP、端口号和项目名称剩下的就是真正的资源访问路径。第5步判断请求类型拿到路径之后判断这个请求是要访问静态资源还是访问 Servlet如果是静态资源CSS、JS、图片、HTML 等就按路径去对应的目录下找文件按相应的编码读取内容直接返回给前端。如果是Servlet 请求就用这个路径作为 key去启动阶段构建的两个 HashMap 里查找。第6步匹配 Servlet 实例和方法从第一个 HashMap 里取出 Servlet 实例从第二个 HashMap 里取出对应的 Method 对象doGet 或 doPost根据请求方式判断。第7步动态代理调用方法拿到实例和方法之后调用 method.invoke(servletInstance, request, response) 来执行 Servlet 的业务方法。这里用的是动态代理。为什么要用代理呢因为编译时我们不知道具体的 Servlet 类名没办法直接写 servlet.doGet(req, resp)。但 invoke() 的三要素和普通方法调用是完全对应的第一个参数是对象实例在哪个对象上调用后面的参数是方法参数。所以本质上和直接调用是一样的只是通过反射动态完成。doGet 和 doPost 都是 void 方法没有返回值它们的处理结果会写到 response 对象里。第8步返回响应最后通过 Socket 的输出流把 response 对象里封装的数据返回给客户端。一次请求处理就完成了。三、总结所以手写 Tomcat 的核心就是启动阶段扫描 → 反射 → 注解 → 实例化 → 存 HashMap请求阶段Socket 接收 → 线程池处理 → 封装 Request/Response → 判断静态资源还是 Servlet → HashMap 匹配 → invoke 调用 → 返回响应而支撑这一切的三大核心技术就是反射、线程池、动态代理。这也是几乎所有 Java 框架的通用模式。

相关新闻

华为MetaERP 一、SLA 设计哲学SLA(Subledger Accounting)是所有子模块到 GL 之间的会计转换引擎,不是记账工具。业财分离 OM/INV/AR 只抛“业务事件“,

华为MetaERP 一、SLA 设计哲学SLA(Subledger Accounting)是所有子模块到 GL 之间的会计转换引擎,不是记账工具。业财分离 OM/INV/AR 只抛“业务事件“,

一、SLA 设计哲学SLA(Subledger Accounting)是所有子模块到 GL 之间的会计转换引擎,不是记账工具。业财分离 OM/INV/AR 只抛"业务事件",不直写 GL;会计规则全收在 SLA,"一套业务、多套财务&…

2026/10/11 8:18:30 阅读更多 →
零基础读懂 Spring Boot AI 网关:从场景定义到调用大模型的完整流程

零基础读懂 Spring Boot AI 网关:从场景定义到调用大模型的完整流程

前言随着大语言模型技术的发展,AI 能力逐渐从单一对话工具转变为可嵌入业务系统的智能服务能力。本项目基于 Spring Boot 与 Spring AI 框架,设计并实现了一套轻量化 AI 网关服务,用于统一管理不同业务场景下的大模型调用流程。传统应用在接入…

2026/10/8 5:36:27 阅读更多 →
Effective C++ 学习笔记 条款39 明智而审慎地使用private继承

Effective C++ 学习笔记 条款39 明智而审慎地使用private继承

条款32 展示了 C 将 public 继承视为 is-a 关系。它通过这样一个例子来说明:当 Student 以 public 方式继承自 Person 时,如果函数调用需要,编译器会隐式地将 Student 转换为 Person。这里值得用 private 继承代替 public 继承,再…

2026/10/9 1:59:00 阅读更多 →

最新新闻

Windows浏览器多开实战:基于user-data-dir实现独立分身与批量管理

Windows浏览器多开实战:基于user-data-dir实现独立分身与批量管理

先说个结论:Windows下让浏览器“多开”这件事,听起来像是随便点几个窗口就行,但真正想做到“开一百个窗口互不干扰、不串号、不崩溃”,完全不是一回事。这段时间我为了给一套多账号运营工作流做技术验证,把浏览器多开从…

2026/10/12 2:56:41 阅读更多 →
互联网医院源码拆包实战:在线问诊与处方流转全链路解析

互联网医院源码拆包实战:在线问诊与处方流转全链路解析

简介:这份互联网医院源码面向医疗信息化开发者与创业团队,用于快速搭建支持在线问诊与在线开处方的远程医疗服务平台,帮助打破地域限制、提升问诊效率。源码围绕患者与医生的即时沟通展开,涵盖文字聊天、语音视频诊疗、病情描述与…

2026/10/12 2:56:41 阅读更多 →
Vagrant多虚拟机实战:VirtualBox兼容、SSH超时与磁盘清理全记录

Vagrant多虚拟机实战:VirtualBox兼容、SSH超时与磁盘清理全记录

最近在重建开发环境时,卡了我整整两天的一件事,就是在一台宿主机上用 Vagrant 同时管理三台虚拟机:CentOS8、Ubuntu22.04 和 Ubuntu24.04。原以为无非就是装三个 box、写一个 Vagrantfile,然后 vagrant up 一把梭。结果从 Virtual…

2026/10/12 2:56:41 阅读更多 →
点云特征识别实战:从法向量估计到FPFH描述子的关键技术

点云特征识别实战:从法向量估计到FPFH描述子的关键技术

简介:这是一份面向C开发者及三维视觉学习者的点云特征识别项目资料,对应CloudPoint完整工程包。内容围绕点云处理经典流程展开:从统计离群点去除、体素滤波等预处理,到区域分割、关键点检测,再到PFH、FPFH、SHOT等特征…

2026/10/12 2:56:41 阅读更多 →
Netty源码地图:从Channel到EventLoop的请求生命周期解析

Netty源码地图:从Channel到EventLoop的请求生命周期解析

学Netty的人很多,但真正打开过Netty源码的人,比想象中少得多。大多数时候我们停留在“会用”的层面:知道Bootstrap怎么配、ChannelHandler怎么写、EventLoopGroup开几个线程,一旦跑到线上出问题,比如连接积压、内存涨、…

2026/10/12 2:56:41 阅读更多 →
MySQL 64学时教学大纲拆解:从E-R图到PetStore建库全链路

MySQL 64学时教学大纲拆解:从E-R图到PetStore建库全链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 2:55:40 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →