学习课程: 【这可能是B站讲的最好的Servlet教程,5小时打通Servlet全套教程丨2022最新版,轻松掌握servlet基础+案例实操】 https://www.bilibili.com/video/BV1Kr4y1V7ZE/?share_source=copy_web&vd_source=2c07d62293f5003c919b2df9b2e0549e
Servlet的生命周期基本介绍
Servleti没有main()方法,不能独立运行,它的运行完全由Servlet引擎来控制和调度。所谓生命周期,指的是servlet容器何时创建servlet实例、何时调用其方法进行请求的处理、何时并销毁其实例的整个过程。
实例和初始化时机
Servlet 通过调用 init () 方法进行初始化。当请求到达容器时,容器查找该servlet对象是否存在,如果不存在,则会创建实例并进行初始化。
就绪/调用/服务阶段
Servlet 调用 service() 方法来处理客户端的请求。有请求到达容器,容器调用servlet对象的service()方法。处理请求的方法在整个生命周期中可以被多次调用;HttpServlet的service()方法,会依据请求方式来调用doGet0或者doPost()方法。但是,这两个do方法默认情况下,会抛出异常,需要子类去override。销毁时机
Servlet 通过调用 destroy() 方法终止(结束)。当容器关闭时(应用程序停止时),会将程序中的Servlet实例进行销毁。最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
上述的生命周期可以通过Servlet中的生命周期方法来观察。在Servlet中有三个生命周期方法,不由用户手动调用,而是在特定的时机有容器自动调用,观察这三个生命周期方法即可观察到Servlet的生命周期。
方法介绍
init方法:在Servlet实例创建之后执行(证明该Servlet有实例创建了)。init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。
Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
init 方法的定义如下:
public void init() throws ServletException { // 初始化代码...}
service方法:每次有请求到达某个Servlet方法时执行,用来处理请求(证明该Servlet进行服务了)。service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
下面是该方法的特征:
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{}
destroy方法:Servlet实例销毁时执行(证明该Servlet的实例被销毁了)。destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下所示:
public void destroy() { // 终止化代码... }
Servlet的生命周期,简单的慨括这就分为四步:servlet类加载->实例化->服务->销毁。下面我们描述一下Tomcat与Servlet是如何工作的,看看下面的时序图:
- Web Client向Servlet容器(Tomcat)发出Http请求
- Servlet容器接收Web Client的请求
- Servlet容器创建一个HttpServletRequest对象,将Web Client请求的信息封装到这个对象中
- Servlet容器创建一个HttpServletResponse对象
- Servlet容器调HttpServlet对象service方法,把Request与Response作为参数,传给HttpServlet
- HttpServlet调用HttpServletRequest对象的有关方法,获取Http请求信息
代码演示:
package com.xxxx.servlet;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/ser05")public class servlet05 extends HttpServlet { /** * 就绪/服务方法(处理请求数据) * 系统方法,服务器自动调用, * 当有请求到达Servlet时,就会调用该方法 * 方法可以被多次调用 * @param req * @param resp * @throws ServletException * @throws IOException */ @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("Servlet被调用..."); } /** * 初始化方法 * 系统方法,服务器自动调用,它在第一次创建 Servlet对象 时被调用 * 当请求到达Servlet容器时,Servlet容器会判断该Servlet对象是否存在,如果不存在,则创建实例,并调用该方法初始化 * 该方法在生命周期中只会执行一次 * @throws ServletException */ @Override public void init() throws ServletException { System.out.println("Servlet被创建了,初始化..."); } /** * 销毁方法 * 系统方法,服务器自动调用,在 Servlet 生命周期结束时被调用 * 当服务器关闭或应用程序停止时,调用该方法 * 方法在生命周期中只会调用一次 */ @Override public void destroy() { System.out.println("Servlet被销毁了..."); }}