精华内容
下载资源
问答
  • servlet生命周期详解

    2012-06-27 08:56:18
    servlet生命周期详解
  • Servlet生命周期详解

    2021-01-23 23:20:29
    Servlet生命周期概述servlet生命周期的四个过程1、实例化servlet对象我们的OOP(面向对象)思想中,总是先创建对象,通过对象调用成员,那么servlet如何实例化呢?设置对应servlet的优先级(loadOnStartup)2、初始化...

    概述

    	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实例进行清除处理

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

    展开全文
  • Servlet 生命周期详解

    2017-08-09 14:38:10
    客户端请求该servlet 加载servlet类到内存 实例化、初始化该servlet init()初始化参数 service()(doGet()或者doPost()) destroy() 加载和实例化Servlet。这项操作一般是动态执行的。然而,Server通常会提供...

    客户端请求该servlet

    加载servlet类到内存

    实例化、初始化该servlet

    init()初始化参数

    service()(doGet()或者doPost())

    destroy()

    加载和实例化Servlet。这项操作一般是动态执行的。然而,Server通常会提供一个管理的选项,用于在Server启动时强制装载和初始化特定的Servlet。

    Server创建一个Servlet的实例

    第一个客户端的请求到达Server

    Server调用Servlet的init()方法(可配置为Server创建servlet实例时调用,在web.xml中<servlet>标签下配置<load-on-startup>标签,配置的值为整型,值越小servlet的启动优先级越高)

    一个客户端的请求到达Server

    Server创建一个请求对象,处理客户端请求

    Server创建一个响应对象,响应客户端请求

    Server激活Servlet的service()方法,传递请求和响应对象作为参数

    service()方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息

    service()方法使用响应对象的方法,将响应传回Server,最终到达客户端。service()方法可能激活其它方法以处理请求,如doGet()或doPost()或程序员自己开发的新的方法。

    对于更多的客户端请求,Server创建新的请求和响应对象,仍然激活此Servlet的service()方法,将这两个对象作为参数传递给它。如此重复以上的循环,但无需再次调用init()方法。一般Servlet只初始化一次(只有一个对象),当Server不再需要Servlet时(一般当Server关闭时),Server调用Servlet的Destroy()方法。

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,832
精华内容 3,932
关键字:

servlet生命周期详解