Servlet 的生命周期是指Servlet从创建到销毁的整个过程,由Servlet容器(如Tomcat)管理。理解生命周期有助于编写高效的Servlet代码并正确处理资源。


目录

  1. 生命周期概述
  2. 生命周期阶段
  1. 生命周期示例
  2. 注意事项
  3. 参考资料

1. 生命周期概述

Servlet 的生命周期包括以下关键阶段:

  1. 加载和实例化:容器加载Servlet类并创建实例。
  2. 初始化:调用 init() 方法进行初始化。
  3. 服务请求:调用 service() 方法处理客户端请求。
  4. 销毁:调用 destroy() 方法释放资源。

这些阶段由Servlet容器自动管理,开发者只需实现特定方法来介入。


2. 生命周期阶段

2.1 加载和实例化

  • 何时发生:容器启动时,或第一次请求到达时(取决于配置)。
  • 作用:加载Servlet的 .class 文件到内存,并通过 new 创建实例。
  • 特点:每个Servlet类通常只有一个实例(单例模式),由容器管理。

配置示例(web.xml 中设置加载时机):

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.example.MyServlet</servlet-class>
    <load-on-startup>1</load-on-startup> <!-- 容器启动时加载 -->
</servlet>

2.2 初始化

  • 方法public void init(ServletConfig config) throws ServletException
  • 何时调用:实例化后立即调用,仅执行一次。
  • 作用
  • 初始化资源(如数据库连接)。
  • 获取配置参数(如 web.xml 中的 <init-param>)。
  • 默认实现GenericServlet 提供,子类可重写。

2.3 服务请求

  • 方法public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
  • 何时调用:每次客户端请求时。
  • 作用
  • 接收请求并生成响应。
  • HttpServlet 中,分派到 doGet()doPost() 等方法。
  • 特点:多线程处理,每个请求由单独线程调用。

2.4 销毁

  • 方法public void destroy()
  • 何时调用:容器关闭时,或Servlet被移除时(仅执行一次)。
  • 作用
  • 释放资源(如关闭文件或数据库连接)。
  • 执行清理操作。

3. 生命周期示例

以下是一个展示Servlet生命周期的完整示例:

代码:LifecycleServlet.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class LifecycleServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config); // 调用父类的init方法
        System.out.println("Servlet 初始化完成");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<h1>Servlet 正在处理请求</h1>");
        System.out.println("处理GET请求");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response); // 简单起见,POST调用GET
    }

    @Override
    public void destroy() {
        System.out.println("Servlet 销毁");
    }
}

配置:web.xml

<web-app>
    <servlet>
        <servlet-name>LifecycleServlet</servlet-name>
        <servlet-class>LifecycleServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>LifecycleServlet</servlet-name>
        <url-pattern>/lifecycle</url-pattern>
    </servlet-mapping>
</web-app>

运行流程

  1. 启动Tomcat:输出“Servlet 初始化完成”。
  2. 访问 http://localhost:8080/myapp/lifecycle:输出“处理GET请求”,页面显示标题。
  3. 关闭Tomcat:输出“Servlet 销毁”。

4. 注意事项

  • 线程安全:Servlet 是单实例多线程,共享变量需同步(如使用 synchronized)。
  • 初始化参数:通过 ServletConfig 获取:
  String param = config.getInitParameter("key");
  • 异常处理init()service() 可抛出 ServletExceptionIOException,需妥善处理。

5. 参考资料

出站链接

其他资源

  • 《Head First Servlets and JSP》 – Servlet入门书籍。
  • X社区:搜索 #ServletLifecycle 获取讨论。

这篇指南详细讲解了Servlet生命周期的每个阶段及其实现方法。如果您需要更深入的内容(如生命周期中的异常处理或与Perl CGI的对比),请告诉我!