Servlet生命周期详解

servlet 专栏收录该内容
7 篇文章 0 订阅

概述

	servlet的生命周期:servlet在容器中开始实例化到实例销毁的整个过程

servlet生命周期的四个过程

1、实例化servlet对象

我们的OOP(面向对象)思想中,总是先创建对象,通过对象调用成员,那么servlet如何实例化呢?

  • 第一种方式:通过配置文件web.xml进行实例化
public class ActionServlet extends HttpServlet {
    //1、构造器
    public ActionServlet(){
        System.out.println("servlet对象实例化中.....");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--配置servlet生命周期的servlet-->
    <servlet>
        <servlet-name>testServlet</servlet-name>
        <servlet-class>org.softeem.controller.ActionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testServlet</servlet-name>
        <url-pattern>/friend_demo/action</url-pattern>
    </servlet-mapping>
</web-app>
  • 第二种方式:注解
//注解方式,效果等同于web.xml中的配置
@WebServlet("/friend_demo/action")
public class ActionServlet extends HttpServlet {
	//1、构造器
    public ActionServlet(){
        System.out.println("servlet对象实例化中.....");
    }
}
  • 通过以上两种方式中的一种,此时运行tomcat会出现如下结果
23-Jan-2021 21:52:28.552 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
23-Jan-2021 21:52:28.554 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 39 ms
Connected to server
[2021-01-23 09:52:29,482] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait...
23-Jan-2021 21:52:29.779 警告 [RMI TCP Connection(3)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default version will be used.
23-Jan-2021 21:52:30.540 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
servlet对象实例化中.....
  • 通过上面的运行结果可以发现,确实调用了ActionServlet 类中的无参构造器。但是,出现该结果是在我们在浏览器客户端中输入了当前servlet对应的 /friend_demo/action 请求后才在控制台中输出 “servlet对象实例化中…”,由此可以发现只有当我们在使用对应的servlet时才会进行对象的创建。有时我们需要某个servlet随着容器加载时就创建servlet对象,而不是在使用时才创建。这是就可以通过设定servlet对应的优先级来决定servlet实例化的时机

设置对应servlet的优先级(loadOnStartup)

设定servlet优先级可以使用loadOnStartup属性,对应的属性值越小优先级别越高。当我们需要servlet与tomcat容器一起加载时而被实例化,即将loadOnStartup属性值设定为1,设定的方式有两种

  • 配置文件方式
<!--配置servlet生命周期案例的servlet-->
   <servlet>
       <servlet-name>testServlet</servlet-name>
       <servlet-class>org.softeem.controller.ActionServlet</servlet-class>
       <!--设定当前servlet与容器加载时加载-->
       <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
       <servlet-name>testServlet</servlet-name>
       <url-pattern>/friend_demo/action</url-pattern>
   </servlet-mapping>
  • 注解方式
    注意:若同时设定请求协议与优先级时,需要将协议赋值给value属性,且中间使用逗号隔开,如下
@WebServlet(value="/friend_demo/action",loadOnStartup = 1)
public class ActionServlet extends HttpServlet {
    //1、构造器
    public ActionServlet(){
        System.out.println("servlet对象实例化中.....");
    }
}

2、初始化参数配置

servlet实例化后就会调用init方法,被设计为只能调用一次,且是在进行第一次实例化servlet对象时调用。当用户在调用servlet时,就会创建一个servlet实例,每一次在客户端发送的请求servlet就会产生一个新的线程,从而调用对应的doGet 或 doPost 方法。init方法的作用在于初始化一些配置参数(比如编码设置),并写这些参数将被贯穿整个servlet生命周期。配置参数的参数有两种,如下

  • 通过配置文件web.xml方式配置
<!--配置servlet生命周期案例的servlet-->
  <servlet>
      <servlet-name>testServlet</servlet-name>
      <servlet-class>org.softeem.controller.ActionServlet</servlet-class>
      <!--设定当前servlet与容器加载时加载-->
      <load-on-startup>1</load-on-startup>
      <!--配置初始化参数,可以同时配置多组-->
      <!--1、配置编码-->
      <init-param>
           <param-name>encoding</param-name>
           <param-value>utf-8</param-value>
       </init-param>
         <!--2、配置昵称-->
       <init-param>
           <param-name>userName</param-name>
           <param-value>上进的小仓鼠</param-value>
       </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>testServlet</servlet-name>
      <url-pattern>/friend_demo/action</url-pattern>
  </servlet-mapping>
@WebServlet(value="/friend_demo/action",loadOnStartup = 1)
public class ActionServlet extends HttpServlet {
   //1、构造器
   public ActionServlet(){
       System.out.println("servlet对象实例化中.....");
   }

   //2、初始化
   @Override
   public void init(ServletConfig config) throws ServletException {
       System.out.println("servlet初始化中......");
       //获取配置的参数值
       String encoding = config.getInitParameter("encoding");
       String userName = config.getInitParameter("userName");
       System.out.println(encoding + "," + userName);
   }
  • 通过注解方式配
@WebServlet(value="/friend_demo/action",loadOnStartup = 1,
initParams = {
       @WebInitParam(name="encoding",value = "utf-8"),
       @WebInitParam(name="userName",value = "上进的小仓鼠")
   }
)
public class ActionServlet extends HttpServlet {
   //1、构造器
   public ActionServlet(){
       System.out.println("servlet对象实例化中.....");
   }

   //2、初始化
   @Override
   public void init(ServletConfig config) throws ServletException {
       System.out.println("servlet初始化中......");
       //获取配置的参数值
       String encoding = config.getInitParameter("encoding");
       String userName = config.getInitParameter("userName");
       System.out.println(encoding + "," + userName);
   }
}

配置完参数运行结果如下:

23-Jan-2021 22:42:05.584 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 29 ms
Connected to server
[2021-01-23 10:42:05,899] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait...
23-Jan-2021 22:42:06.062 警告 [RMI TCP Connection(3)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default version will be used.
23-Jan-2021 22:42:06.657 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
servlet对象实例化中.....
servlet初始化中......
utf-8,上进的小仓鼠

3、就绪状态

service()方法是执行实际任务的主要方法,Web服务器将调用service方法处理客户端(浏览器)的请求,然后将格式化的数据响应给浏览器客户端。每当客户端向服务端发送一个请求时,服务端都会产生一个新的线程调用服务。service方法将会检测客户端发送给服务端的HTTP请求协议的类型,从而调用service方法中的 doGet、doPost、doPut、doDelete 等方法进行实际任务的逻辑处理,其中的执行流程图如下
在这里插入图片描述
单个servlet执行流程
单个servlet执行流程

  • 案例代码如下
@WebServlet(value="/friend_demo/action",loadOnStartup = 1,
initParams = {
       @WebInitParam(name="encoding",value = "utf-8"),
       @WebInitParam(name="userName",value = "上进的小仓鼠")
   }
)
public class ActionServlet extends HttpServlet {
   //1、构造器
   public ActionServlet(){
       System.out.println("servlet对象实例化中.....");
   }

   //2、初始化
   @Override
   public void init(ServletConfig config) throws ServletException {
       System.out.println("servlet初始化中......");
       //获取配置的参数值
       String encoding = config.getInitParameter("encoding");
       String userName = config.getInitParameter("userName");
       System.out.println(encoding + "," + userName);
   }

   //3、就绪状态
   @Override
   public void service(HttpServletRequest request, HttpServletResponse response)
       throws IOException, ServletException {
       System.out.println("servlet:service()就绪中...");
   }
}

程序运行结果如下

23-Jan-2021 22:42:15.575 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory D:\apache\apache-tomcat-8.0.45\webapps\manager
23-Jan-2021 22:42:15.594 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory D:\apache\apache-tomcat-8.0.45\webapps\manager has finished in 18 ms
[2021-01-23 10:54:32,996] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait...
servlet实例销毁中....
servlet对象实例化中.....
servlet初始化中......
utf-8,小仓鼠
[2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Artifact is deployed successfully
[2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Deploy took 1,128 milliseconds
servlet:service()就绪中...

4、销毁状态

servlet生命周期结束时将会调用destroy()方法,并且只会调用一次。destroy方法可以让我们的servlet关闭数据库连接,把后台线程关闭,清楚Cookie数据等。当调用了destroy()方法后,当前servlet实例将会被标记为回收垃圾,会对servlet实例进行清除,案例代码如下

@WebServlet(value="/friend_demo/action",loadOnStartup = 1,
initParams = {
        @WebInitParam(name="encoding",value = "utf-8"),
        @WebInitParam(name="userName",value = "上进小仓鼠")
    }
)
public class ActionServlet extends HttpServlet {
    //1、构造器
    public ActionServlet(){
        System.out.println("servlet对象实例化中.....");
    }

    //2、初始化
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("servlet初始化中......");
        //获取配置的参数值
        String encoding = config.getInitParameter("encoding");
        String userName= config.getInitParameter("userName");
        System.out.println(encoding + "," + userName);
    }

    //3、就绪状态
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
        System.out.println("servlet:service()就绪中...");
    }

    //4、销毁状态
    @Override
    public void destroy() {
        System.out.println("servlet实例销毁中....");
    }
}

执行程序后的运行效果

[2021-01-23 10:54:32,996] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait...
servlet实例销毁中....
servlet对象实例化中.....
servlet初始化中......
utf-8,小仓鼠
[2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Artifact is deployed successfully
[2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Deploy took 1,128 milliseconds
servlet:service()就绪中...
[2021-01-23 11:06:03,372] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait...
servlet实例销毁中....

servlet生命周期总结

  • 实例化:servlet容器创建servlet对象。默认创建servlet实例的时机:当我们发送servlet对应的请求时(在使用时创建)。类似单例模式中的懒加载方式。希望容器一旦启动,就自动创建servlet实例通过load-on-startup=1设置,正数数值越低优先级别越高,优先实例化

  • 初始化:servlet实例一旦创建,就开始初始化一些参数配置,我们可以做一些参数配置,比如编码,可以在web.xml或注解中配置

  • 就绪状态:当发送对应的servlet请求时,会调用service()方法,注意此时不会重新创建servlet实例,也不会调用init()方法

  • 销毁状态:调用了destroy()方法后,当前servlet实例将会被标记为回收垃圾,会对servlet实例进行清除处理

详细请参考上面…
感谢大家的支持,我会继续提高相关技术…

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值