当前位置:首页 > 技术 > 正文内容

Servlet 生命周期详解

访客 技术 2026年10月27日 2

Servlet 的生命周期是指从 Servlet 对象被创建到被销毁的整个过程,包括其创建时机、销毁时机以及实例数量等。

Servlet 对象的管理

Servlet 对象的创建、方法调用以及销毁等一系列操作,通常不由 Java Web 开发者直接干预,而是由 Web 服务器(如 Tomcat)全权负责。Web 服务器中的这部分组件被称为 Web 容器。

手动实例化 Servlet 的影响

开发者手动使用 new 关键字创建的 Servlet 对象,并不受 Web 容器的管理。只有由 Web 容器创建并维护的 Servlet 对象,才会被纳入其管理范畴。Web 容器内部通常维护着一个集合(类似 HashMap),用于存储 Servlet 对象及其与请求路径的映射关系。

Servlet 对象的预加载

默认情况下,Web 服务器启动时并不会立即实例化所有的 Servlet 对象。这是一种合理的资源优化策略,避免在用户尚未发送请求时就消耗不必要的内存。如果在用户未访问之前就创建了大量 Servlet 对象,而这些对象又一直未被使用,则会造成资源浪费。

配置 Servlet 预加载

可以通过在 web.xml 配置文件中使用 <load-on-startup> 标签来配置 Servlet 在服务器启动时即被创建。该标签可以接受一个整数值,数值越小,优先级越高,表示越先被加载。


<servlet>
    <servlet-name>myServlet</servlet-name>
    <servlet-class>com.example.MyServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>myServlet</servlet-name>
    <url-pattern>/myservlet</url-pattern>
</servlet-mapping>

Servlet 生命周期详解

当服务器启动时,如果未配置 <load-on-startup>,Servlet 对象(如 MyServlet)的构造方法默认不会执行。

首次请求处理:

  • 用户发送第一次请求时,Web 容器会执行以下操作:
    • 实例化 Servlet 对象(调用无参构造方法)。
    • 调用 Servlet 对象的 init() 方法。
    • 调用 Servlet 对象的 service() 方法来处理请求。

此时的控制台输出可能如下:


MyServlet constructor executed.
MyServlet init method executed.
MyServlet service method executed.

后续请求处理:

  • 用户发送后续请求时,Web 容器会重用已创建的 Servlet 实例,并直接调用其 service() 方法。

此时的控制台输出可能如下:


MyServlet service method executed.

关键结论:

  1. 单实例性: Servlet 对象是单实例的。虽然 Servlet 类本身不符合严格的单例模式(构造方法非私有),但由于其创建由 Web 容器控制,且容器通常只创建一个实例,因此表现出单例的特性。
  2. 方法调用频率:
    • 无参构造方法:仅在 Servlet 对象首次创建时执行一次。
    • init() 方法:仅在 Servlet 对象首次创建后被 Web 容器调用一次。
    • service() 方法:每次接收到客户端请求时,都会被 Web 容器调用一次。

服务器关闭:

  • 当服务器正常关闭时,Web 容器会调用 Servlet 对象的 destroy() 方法。
  • destroy() 方法的执行发生在 Servlet 对象内存被释放之前,用于执行一些清理操作。

此时的控制台输出可能如下:


MyServlet destroy method executed.

Servlet 方法类比人生:

  • 构造方法:出生。
  • init() 方法:接受教育/准备。
  • service() 方法:工作/服务。
  • destroy() 方法:临终/善后。

关于自定义构造方法的注意事项

如果在 Servlet 类中定义了带参数的构造方法,但没有显式定义无参构造方法,Web 容器将无法通过默认方式实例化 Servlet 对象,这通常会导致 HTTP 500(Internal Server Error)错误。因此,在 Servlet 开发中,不建议自定义构造方法,以避免潜在的实例化问题。

init() 方法的必要性

虽然 init() 方法和无参构造方法都在对象首次创建时执行一次,但 init() 方法具有其存在的必要性。Servlet 规范推荐开发者不手动定义构造方法,以确保 Servlet 可被正确实例化。init() 方法提供了一个标准化的入口点,用于执行一次性的初始化操作,例如初始化数据库连接池或线程池。

常用方法分析

  • service() 方法: 是最常用的方法,必须实现,因为它是处理客户端请求的核心逻辑所在。
  • init() 方法: 使用频率较低,通常用于执行一次性的资源初始化,如连接池的配置。
  • destroy() 方法: 使用频率也很低,主要用于在 Servlet 对象被销毁前执行资源释放操作,如关闭数据库连接等。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

PHPStan 有什么用?怎么用?

PHPStan 是一个 PHP 的静态分析工具,在不运行代码的情况下就能帮你发现潜在问题,比如:传错类型(把 string 传给接受 int 的函数)访问不存在的属性 / 方法null 没处理好永远不会执行到的代码数组 key/值类型不一致返回值不符合声明注释和真实类型不匹配它非常适合:想提升代码质量、减少线上 bug、统一团队风格的人(尤其是中大型项目)。一、PHPStan 有什么用(通俗点说)...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。