Servlet 生命周期

Servlet 生命周期(完整解析)

Servlet 是 Java Web 核心组件,其生命周期完全由 Servlet 容器(如 Tomcat) 管理,从创建到销毁分为 初始化、请求处理、销毁 三个核心阶段,还包含加载与实例化的前置环节,整体流程如下:

一、生命周期完整阶段(按执行顺序)
阶段 触发时机 核心方法 执行次数 核心说明
1. 加载与实例化 ① 容器启动时(<load-on-startup> 配置);② 首次请求该 Servlet 时 无(容器调用构造方法) 仅 1 次 容器通过反射创建 Servlet 实例(默认单例,多实例需配置 SingleThreadModel
2. 初始化 实例化后立即执行 init(ServletConfig) 仅 1 次 初始化资源(如数据库连接、配置加载),可通过 ServletConfig 获取初始化参数
3. 请求处理 客户端发送请求(GET/POST 等)时 service(ServletRequest, ServletResponse)(底层调用 doGet/doPost 多次(每次请求) 核心业务逻辑处理,容器为每个请求分配独立线程,需注意线程安全
4. 销毁 ① 容器关闭;② 应用卸载;③ 容器检测到 Servlet 长时间未使用(极少触发) destroy() 仅 1 次 释放资源(如关闭连接、清理缓存),销毁后实例被垃圾回收
二、核心方法详解
1. 构造方法(实例化阶段)
  • 由容器调用,默认无参构造,若自定义有参构造需保证无参构造存在(否则容器无法实例化);
  • 单例模式下仅执行一次,所有请求共享同一个 Servlet 实例(需注意成员变量线程安全)。
2. init (ServletConfig config) 方法
  • 初始化入口,容器自动传入 ServletConfig 对象(包含 Servlet 名称、初始化参数、ServletContext);

  • 可重写 init() 无参方法(底层仍调用 init(ServletConfig)),示例:

    复制代码
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config); // 必须调用,否则ServletConfig无法被获取
        // 初始化数据库连接
        String dbUrl = config.getInitParameter("dbUrl");
        System.out.println("Servlet初始化,数据库地址:" + dbUrl);
    }
3. service (ServletRequest req, ServletResponse resp) 方法
  • 容器接收到请求后,先调用 service 方法,根据请求方式(GET/POST/PUT 等)自动分发到对应 doXxx 方法;

  • 若未重写 doGet/doPost,默认抛出 HttpServletMethodNotSupportedException

  • 示例(HttpServlet 子类):

    复制代码
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp); // 父类实现请求分发逻辑
        System.out.println("处理请求:" + req.getMethod());
    }
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("处理GET请求");
    }
4. destroy () 方法
  • 容器销毁 Servlet 前调用,用于释放资源,示例:

    复制代码
    @Override
    public void destroy() {
        // 关闭数据库连接、清理线程池等
        System.out.println("Servlet销毁,释放资源");
    }
三、关键特性与注意事项
  1. 单例特性:默认情况下,一个 Servlet 类在容器中仅存在一个实例,所有请求共用该实例 → 避免在 Servlet 中定义可变成员变量(易引发线程安全问题),建议使用局部变量或 ThreadLocal。

  2. 加载时机控制

    • 默认:首次请求时加载实例化(懒加载);

    • 配置 <load-on-startup>1</load-on-startup>(web.xml)或 @WebServlet(loadOnStartup = 1):容器启动时立即加载,数字越小优先级越高(用于初始化核心服务)

      MyServlet com.example.MyServlet 1 dbUrl jdbc:mysql://localhost:3306/test MyServlet /myServlet
  3. ServletContext 作用域 :生命周期贯穿整个 Web 应用,可通过 getServletContext() 获取,用于共享应用级数据(如全局配置)。

四、生命周期流程图(简化)
复制代码
容器启动/首次请求 → 加载Servlet类 → 实例化(构造方法) → init()初始化 → 
↓(每次请求)
service() → doGet/doPost处理请求 → 
↓(容器关闭/应用卸载)
destroy()销毁 → 实例被GC回收
相关推荐
躺柒13 小时前
读数据架构知识体系指南01关系数据仓库(上)
数据仓库·架构·数据分析·spark·数据湖·关系数据库·企业数据仓库
卷毛迷你猪14 小时前
快速实验篇(A9-2)Python vs MapReduce:小批量任务的工具选择
大数据·hadoop
姜穆澜14 小时前
Apache Hive 4.x 完全学习指南
大数据·hive
Ahtacca2 天前
hadoop部署前置准备
hadoop
tianhuo0032 天前
从MySQL到Apache Doris:生鲜供应链数仓的ETL流水线与SARIMA需求预测全实
数据仓库·数据中台·零售行业供应链数字化
计算机源码社2 天前
基于K-Means聚类的新生儿败血症临床分型与可视化分析系统 基于数据挖掘的新生儿败血症生命体征时序走势与关联性可视化研究
大数据·hadoop·python·数据挖掘·数据分析·spark·毕业设计
SendTomo2 天前
.ico透明图标在线生成下载平台深度解析
大数据·数据结构·数据库·数据仓库·个人开发
计算机源码社3 天前
基于大数据的全球温室气体排放燃料结构与碳强度评估研究-基于Spark的全球温室气体排放多维度检测与评估分析
大数据·hadoop·python·数据挖掘·数据分析·spark·毕业设计
qingwufeiyang_5303 天前
IceBerg学习笔记2
数据仓库·数据湖
Q26433650233 天前
【有i源码】基于大数据的城市交通流量与出行特征可视化分析平台-基于Hadoop的城市交通拥堵关联规则与异常检测研究
大数据·hadoop·机器学习·数据挖掘·数据分析·spark·数据可视化