/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
在 Java Web 开发体系中,Servlet 是所有 Web 程序的底层基石。我们后续接触的 SpringMVC、SpringBoot 等主流 Web 框架,底层核心能力都构建在 Servlet 规范之上。这篇笔记从基础概念、生命周期、底层调用原理到分层继承体系,完整梳理 Servlet 的核心知识,帮你建立清晰的知识体系。
一、Servlet 基础概念:到底什么是 Servlet
1.1 本质与技术定位
Servlet 本质上是一个Java 接口,它是Java Web 开发的核心底层规范。Java语言之所以能进行Web 端程序的开发,并实现 “ 接收网络请求 + 业务处理 + 返回相应 ” 的完整Web 服务能力,底层正是依托 Servlet 接口定义的统一契约。
1.2 接口的功能语义
在Java 语法中,接口的核心作用是定义功能契约:一个类实现对应接口后,就具备了该接口描述的能力。
Servlet 接口定义的核心功能就是:接收客户端的网络请求,完成业务逻辑处理之后,向客户端返回响应结果。
一个普通的Java 类只要实现了 Servlet 接口,就拥有了处理 Web 请求的能力,可以作为Web 服务的处理组件。
Web 服务的核心工作流程可以概括为三步:
接收客户端请求 → 执行内部业务逻辑 → 向客户端返回处理结果
二、Servlet 生命周期:从创建到销毁的全流程
Servlet 有一套完整的生命周期管控机制,全程由 Web 容器(以 Tomcat 为代表)负责调度,核心包含四个阶段:构造方法、init 初始化、service 处理请求、destroy 销毁。
2.1 四个核心阶段详解
| 构造方法 | 第一次访问 Servlet 时执行 | 整个生命周期仅 1 次 | 创建 Servlet 的实例对象,默认调用无参构造器 |
| init 方法 | 对象创建完成后,首次处理请求前执行 | 整个生命周期仅 1 次 | 完成初始化工作,比如加载配置、初始化资源等一次性准备 |
| service 方法 | 每一次客户端请求都会执行 | 可执行多次,请求多少次就执行多少次 | Servlet 核心业务方法,负责解析请求、执行业务、生成响应 |
| destroy 方法 | Web 服务器(Tomcat)正常关闭时执行 | 整个生命周期仅 1 次 | 销毁前收尾,释放占用的资源、保存临时数据等 |
补充语法说明:init、service、destroy 均为非静态方法,非静态方法的调用必须依赖类的实例对象,因此必须先创建 Servlet 对象,才能执行这些方法。
这里的构造方法默认为无参构造方法
2.2 完整执行流程
- 首次请求:调用无参构造创建对象 → 执行 init 初始化 → 执行 service 处理请求
- 后续重复请求:不再创建新对象、不再执行 init,直接调用 service 方法处理
- 服务器关闭:调用 destroy 方法,销毁对象、释放资源
2.3 单例特性
Servlet 是典型的单例模式:一个 Servlet 类在 Web 容器中只会创建一个实例对象,多次请求共享同一个实例,重复调用 service 方法处理请求。
三、Tomcat 底层调用原理:Servlet 是怎么跑起来的
我们编写的 Servlet 类,既没有手动创建对象,也没有手动调用方法,全部逻辑都由 Tomcat 容器自动完成。
3.1 请求匹配:找到目标 Servlet
Tomcat 接收到客户端请求后(例如请求路径 /hello),会根据请求路径,通过注解或配置的映射关系,匹配到对应的 Servlet 类。
- 404 错误:访问的资源不存在,通常是请求路径拼写错误,没有匹配到对应的 Servlet
- 500 错误:服务器内部异常,URL 路径匹配正确,但 Servlet 代码执行过程中抛出了异常
3.2 反射创建对象
匹配到 Servlet 类后,Tomcat 并不是直接通过 new 关键字创建对象,而是通过Java 反射机制动态创建实例
反射的Java 实现动态创建对象的核心能力,也是各类框架实现:自动装配、解耦开发 的底层基础。
3.3 生命周期方法调度
对象创建完成后,Tomcat 会严格按照生命周期规则,依次调度 init 方法、service 方法,完成请求的处理流程。
四、Servlet 继承体系:分层涉及简化开发
如果直接实现 Servlet 接口,需要重写 5 个抽象方法,但是世界开发中,我们只关心请求处理的业务逻辑,其余方法大都是固定模板。
为了简化开发、提升效率,Servlet 规范设计了分层继承体系,通过父类封装通用逻辑,子类只关注核心业务。
4.1 完整继承层级
继承链从上到下为:
自定义 Servlet 类 → HttpServlet → GenericServlet → Servlet 接口
每一层承担不同的职责,逐层封装通用逻辑,最终让开发者只需要编写最少的业务代码。
4.2 每一层的职责
第一层:Servlet 接口
顶层规范,定义了 Servlet 核心的 5 个抽象方法(init、service、destroy、getServletConfig、getServletInfo),约定了所有 Servlet 必须具备的能力。
第二层:GenericServlet
实现了 Servlet 接口,对接口中 5 个方法做了默认实现,同时封装了 ServletConfig 相关的通用逻辑。
它的核心作用是:抽离与 HTTP 协议无关的通用逻辑,屏蔽底层接口的繁琐方法,让上层不用关心无关细节。
第三层:HttpServlet
继承自 GenericServlet,专门针对 HTTP 协议做了封装,是开发中最常用的父类。
它重写了 service 方法,核心完成两件事:
第四层:自定义 Servlet
开发者自己编写的类,只需要继承 HttpServlet,根据业务需求重写 doGet、doPost 等方法,编写业务逻辑即可。
不需要再关心对象创建、初始化、请求类型判断等通用逻辑,极大降低了开发成本。
4.3 设计思想
这种分层继承的设计,是经典的模板方法模式:父类封装固定的流程(请求分发、类型转换、生命周期默认实现),子类只实现可变的业务部分。既复用了通用代码、减少重复劳动,又保留了足够的扩展性,是 Java 代码复用的典型实践。

