Servlet的生命周期

Posted Ran959

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet的生命周期相关的知识,希望对你有一定的参考价值。

Servlet的生命周期

servlet的生命周期顾名思义就是从servlet出现到消亡(销毁)的全过程。

主要分为以下几个阶段:
加载类—>实例化(为对象分配空间)—>初始化(为对象的属性赋值)—>请求响应(服务阶段)—>销毁

servlet生命周期三个方法:

init()初始化阶段

service()处理客户端请求阶段

destroy()终止阶段

​ 容器(tomcat等)装载servlet

实例化阶段

1.1 当客户端首次发送第一次请求后,由Servlet容器去解析请求,根据请求找到是否有对应的servlet。
1.2 判断是否有Servlet实现类的对象存在?存在则直接使用,不存在则先创建一个servlet实现类的对象。

初始化阶段

Servlet 初始化是其生命周期的第一个阶段,也是其他阶段的基础。只有完成了初始化,Servlet 才能处理来自客户端的请求。

Servlet 初始化阶段分为 2 步:

  1. 加载和实例化 Servlet;
  2. 调用 init() 方法进行初始化

1.加载和实例化

Servlet 容器负责加载和实例化 Servlet。

当容器启动或首次请求某个 Servlet 时,容器会读取 web.xml (配置load-on-startup=1,默认为0)或 @WebServlet 中的配置信息,对指定的 Servlet 进行加载。加载成功后,容器会通过反射对 Servlet 进行实例化。

2.调用 init() 方法进行初始化

加载和实例化完成后,Servlet 容器会创建一个servlet对象并调用servlet的init方法(在servlet生命周期内只能调用一次init方法)去初始化 Servlet 实例。

请求响应阶段

初始化完成后调取service()方法,由service()判断客户端的请求方式。
3.1 如果是get请求,则执行doGet()方法。
3.2 如果是post请求,则执行doPost()。
3.3 处理方法完成后会作出相应的结果返回给客户端,单次请求处理完毕。

当用户发送第二次以后的请求时,会判断对象是否存在,但是不再执行init(),而直接执行service方法调取doGet() / doPost()方法。
 

服务终止阶段

当服务器关闭,重启或移除 Servlet 实例时Servlet调取destroy()方法进行销毁,宣告生命周期的结束。

public class EmpServlet extends HttpServlet
    //初始化servlet,调用init方法
  
    public void init() throws ServletException
        System.out.println("初始化时调用");
    
    //开启服务
  
    protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException
        System.out.println("开启服务时调用");
    

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
        
    
    //销毁时调用destory


    public void destroy()
        System.out.println("销毁时调用");
    

 

Servlet编程:Servlet的生命周期

  1. 如何开发一个Servlet

  2. Servlet的映射路径

  3. Servlet缺省路径

  4. Sevlet的生命周期

  5. Servlet的自动加载

  6. 有参的init方法和无参的init方法

  7. Servlet的多线程并发问题

  8. ServletConfig对象

  9. ServletContext对象

4、Servlet的生命周期



4.1、引入


Servlet的生命周期涉及3个问题: servlet类对象什么时候创建,什么时候调用什么方法,什么时候销毁。

以前的对象,其生命周期由程序开发者编写决定,例如:

Student stu = new Student();//创建Student对象

stu.study();//调用方法

stu = null;//告诉垃圾回收器GC,该对象可以进行回收了


Servlet程序的生命周期由tomcat服务器控制的!!!!


4.2、Servlet生命周期的四个重要方法



Servlet生命周期的4个重要方法
序号方法调用时机和次数
1构造方法创建servlet对象的时候调用。默认情况下,第一次访问servlet的时候创建servlet对象只调用1次。servlet对象在tomcat是单实例的。
2init方法创建完servlet对象的时候调用。只调用1次。
3service方法每次发出请求时调用。调用n次。
4destroy方法销毁servlet对象的时候调用。停止服务器或者重新部署web应用时销毁servlet对象。只调用1次。

案例:验证Servlet生命周期的4个重要方法的调用次数

LifeDemo.java

package com.rk.http.b_lifecycle;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;

public class LifeDemo extends HttpServlet
{
	//1、构造方法
	public LifeDemo()
	{
		System.out.println("1、LifeDemo对象被创建!");
	}
	
	//2、init方法
	@Override
	public void init(ServletConfig config) throws ServletException
	{
		System.out.println("2、调用LifeDemo对象的init方法");
	}
	
	//3、service方法
	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
	{
		System.out.println("3、调用LifeDemo对象的service方法");
	}

	//4、destroy方法
	@Override
	public void destroy()
	{
		System.out.println("4、LifeDemo对象销毁");
	}
}

web.xml配置

  <servlet>
  	<servlet-name>LifeDemo</servlet-name>
  	<servlet-class>com.rk.http.b_lifecycle.LifeDemo</servlet-class>
  </servlet>  
  <servlet-mapping>
    <servlet-name>LifeDemo</servlet-name>
    <url-pattern>/life</url-pattern>
  </servlet-mapping>


使用URL(http://localhost:8080/myweb/life)访问5次后,停止Tomcat,得到如下输出:

1、LifeDemo对象被创建!
2、调用LifeDemo对象的init方法
3、调用LifeDemo对象的service方法
3、调用LifeDemo对象的service方法
3、调用LifeDemo对象的service方法
3、调用LifeDemo对象的service方法
3、调用LifeDemo对象的service方法
五月 23, 2016 11:20:45 上午 org.apache.coyote.http11.Http11AprProtocol pause
信息: Pausing Coyote HTTP/1.1 on http-8080
五月 23, 2016 11:20:45 上午 org.apache.coyote.ajp.AjpAprProtocol pause
信息: Pausing Coyote AJP/1.3 on ajp-8009
五月 23, 2016 11:20:46 上午 org.apache.catalina.core.StandardService stop
信息: Stopping service Catalina
五月 23, 2016 11:20:46 上午 org.apache.catalina.core.ApplicationContext log
信息: SessionListener: contextDestroyed()
五月 23, 2016 11:20:46 上午 org.apache.catalina.core.ApplicationContext log
信息: ContextListener: contextDestroyed()
4、LifeDemo对象销毁
五月 23, 2016 11:20:46 上午 org.apache.coyote.http11.Http11AprProtocol destroy
信息: Stopping Coyote HTTP/1.1 on http-8080
五月 23, 2016 11:20:46 上午 org.apache.coyote.ajp.AjpAprProtocol destroy
信息: Stopping Coyote AJP/1.3 on ajp-8009

4.3、javax.servlet.Servlet源码

package javax.servlet;

import java.io.IOException;


/**
 * 对Servlet进行介绍
 * A servlet is a small Java program that runs within a Web server.
 * Servlets receive and respond to requests from Web clients,
 * usually across HTTP, the HyperText Transfer Protocol. 
 * 
 * 实现Servlet接口的两种方法
 * To implement this interface, you can write a generic servlet
 *that extends
 *<code>javax.servlet.GenericServlet</code> or an HTTP servlet that
 *extends <code>javax.servlet.http.HttpServlet</code>.
 *
 *Servlet接口中定义了一些方法,称为life-cycle methods
 *This interface defines methods to initialize a servlet,
 *to service requests, and to remove a servlet from the server.
 *These are known as life-cycle methods and are called in the
 *following sequence:
 *
 *life-cycle methods的调用顺序如下:The servlet is constructed-->init-->service-->destory
 *The servlet is constructed, then initialized with the <code>init</code> method.
 *Any calls from clients to the <code>service</code> method are handled.
 *The servlet is taken out of service, then destroyed with the 
 *<code>destroy</code> method, then garbage collected and finalized.
 *
 *Servlet接口还提供了另外两个方法:getServletConfig和getServletInfo
 *In addition to the life-cycle methods, this interface
 *provides the <code>getServletConfig</code> method, which the servlet 
 *can use to get any startup information, and the <code>getServletInfo</code>
 *method, which allows the servlet to return basic information about itself,
 *such as author, version, and copyright.
 *
 */
public class Servlet
{
	/**
	 * The servlet container calls the <code>init</code>
	 * method exactly once after instantiating the servlet.
	 * The <code>init</code> method must complete successfully
	 * before the servlet can receive any requests.
	 */
	public void init(ServletConfig config) throws ServletException;
	
	/**
	 * Called by the servlet container to allow the servlet to respond to a request.
	 * This method is only called after the servlet‘s <code>init()</code> method has completed successfully.
	 * 
	 * Servlets typically run inside multithreaded servlet containers
	 * that can handle multiple requests concurrently. Developers must 
	 * be aware to synchronize access to any shared resources such as files,
	 * network connections, and as well as the servlet‘s class and instance variables. 
	 */
	public void service(ServletRequest req, ServletResponse res)
			throws ServletException, IOException;
	
	/**
	 * Called by the servlet container to indicate that the servlet is being taken out of service.
	 * This method is only called once all threads within the servlet‘s
	 * <code>service</code> method have exited or after a timeout period has passed.
	 * After the servlet container calls this method, it will not call 
	 * the <code>service</code> method again on this servlet.
	 * 
	 * This method gives the servlet an opportunity 
	 * to clean up any resources that are being held (for example, memory,
	 * file handles, threads) and make sure that any persistent state is
	 * synchronized with the servlet‘s current state in memory.
	 */
	public void destroy();
	
	/**
	 * Returns a <code>ServletConfig</code> object, which contains initialization and startup parameters for this servlet.
	 * The <code>ServletConfig</code> object returned is the one passed to the <code>init</code> method. 
	 */
	public ServletConfig getServletConfig();
	
	/**
	 * Returns information about the servlet, such as author, version, and copyright.
	 */
	public String getServletInfo();
}





4.4、伪代码演示Servlet的生命周期

Tomtcat内部代码运行:

1)通过映射找到到servlet-class的内容

字符串:com.rk.http.b_lifecycle.LifeDemo

2)通过反射构造LifeDemo对象

2.1 得到字节码对象

Class clazz = class.forName("com.rk.http.b_lifecycle.LifeDemo");

2.2 调用无参数的构造方法来构造对象

Object obj = clazz.newInstance();     ---1.servlet的构造方法被调用

3)创建ServletConfig对象,通过反射调用init方法

3.1 得到方法对象

Method m = clazz.getDeclareMethod("init",ServletConfig.class);

3.2 调用方法

m.invoke(obj,config);             --2.servlet的init方法被调用

4)创建request,response对象,通过反射调用service方法

4.1 得到方法对象

Method m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);

4.2 调用方法

m.invoke(obj,request,response);  --3.servlet的service方法被调用

5)当tomcat服务器停止或web应用重新部署,通过反射调用destroy方法

5.1 得到方法对象

Method m = clazz.getDeclareMethod("destroy",null);

5.2 调用方法

m.invoke(obj,null);            --4.servlet的destroy方法被调用



4.5、用时序图来演示servlet的生命周期

技术分享




以上是关于Servlet的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

JSP 和 Servlet 的工作原理和生命周期

javaweb学习总结二十一(servlet开发入门servlet生命周期以及调用过程)

javaWeb中servlet开发——Servlet生命周期

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器过滤器等Web组件以及MVC架构

java面试题03

Servlet——Java Web Application及Servlet生命周期