欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

读源码学Servlet(3)Servlet的生命周期

程序员文章站 2022-05-24 21:03:53
...


在javax.servlet.Servlet接口中,定义了针对Servlet生命周期最重要的三个方法,按照顺序,依次是init(),Serveice()和destroy()这三个方法.
.

Servlet初始化阶段,包括执行如下四个步骤:
1. servlet容器(如tomcat)加载servlet类,读入其.class类文件到内存
2. servlet容器开始针对这个servlet,创建ServletConfig对象
3. servlet容器创建servlet对象
4. servlet容器调用servlet对象的init(ServletConfig config)方法,在这个init方法中,建立了sevlet对象和servletConfig对象的关联,执行了如下的代码:

 

 

    public void init(ServletConfig config) throws ServletException 
    {   
      this.config = config;  //将容器创建的servletConfig 对象传入,并使用私有成员变量引用该servletConfig对象   
      this.init();    
    }

 

 

通过以上的初始化步骤建立了servlet对象和sevletConfig对象的关联,而servletConfig对象又和当前容器创建的ServleContext对象获得关联.

 

运行时阶段:
当容器接受到访问特定的servlet请求时,针对这个请求,创建对应的ServletRequest对象和ServletResponse对象,并调用servlet的service()方法,service()根据从ServletRequest对象中获得客户的请求信息
并将调用相应的doxxx方法等进行响应,再通过ServletResponse对象生成响应结果,然后发送给客户端,最后销毁创建的ServletRequest 和ServletResponse

 

 

销毁阶段:
只有当web应用被终止时,servlet才会被销毁。servlet容器现调用web应用中所有的Servlet对象的destroy()方法,然后再销毁这些servlet对象,此外,容器还销毁了针对各个servlet所创建的相关联的serveltConfig对象

以下程序代码演示了Servlet对象的生命周期:

 

/*
 * 本程序代码演示了Servlet周期中init()、serveic()、destroy() 三个方法的调用的情况
 * Author: Laurence Luo 
 * Date; 2009-10-21 
 * 
 * 
 */

package com.longweir;


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

public class LifeServlet extends HttpServlet
 {  
   private int initvar=0;
    private int servicevar=0;
    private int destroyvar=0;
    private String name;

    //覆盖父类的销毁方法,加入销毁的计数器
  public void destroy() 
  {
        destroyvar++;
        System.out.println(name+">destroy()被销毁了"+destroyvar+"次");
  }

 
    //覆盖父类的init(ServletConfig config)方法 加入计数
  /*  public void init(ServletConfig config) throws ServletException 
  {
    super.init(config);  //调用父类的带参数的init方法
    name=config.getServletName();
    initvar++;
    System.out.println(name+">init():Servlet 被初始化了"+initvar+"次"); 
  
  }*/
 
 
 /* 根据分析GenericServlet的源码,其init(ServletConfig config)方法最终还是会调用了不带参数的init()方法,
  * 所以也可以在自己编写的的servlet中覆盖不带参数的init()方法来加入统计计数
*/
  
  public void init()  //覆盖父类的不带参数的初始化方法
  {
  initvar++;
  //name=getServleConfig.getServletNmae();
  name=getServletName();  //直接返回
  System.out.println(name+"init(): servlet被初始化了了 "+initvar+"次");
  }
 */
 
 
 public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException 
 {
  servicevar++;  //请求服务计数器自增
  System.out.println(name+">service():servlet共响应了"+servicevar+"请求");
  
  String content1="初始化次数: "+initvar;
  String content2="销毁次数: "+destroyvar;
  String content3="请求服务次数 "+servicevar;
  response.setContentType("text/html;charset=GBK");
  PrintWriter out=response.getWriter();
  out.print("<html><head><title>LifeServlet</title></head>");
  out.print("<body>");
  out.print("<h1>"+content1+"</h1><br>");
  out.print("<h1>"+content2+"</h1><br>");
  out.print("<h1>"+content3+"</h1><br>");
  out.print("</body>");
  out.print("</head>");
  out.close();
 }
 

}