大多數(shù)程序員都知道Servlet的生命周期,簡單的概括這就分為四步:servlet類加載--->實例化--->服務--->銷 毀。對這個過程只是膚淺了解下,對于servlet何時被銷毀,還是不太情楚。下面我們描述一下Tomcat與Servlet是如何工作的,首先看下面的 時序圖.

1、Web Client 向Servlet容器(Tomcat)發(fā)出Http請求
2、Servlet容器接收Web Client的請求
3、Servlet容器創(chuàng)建一個HttpRequest對象,將Web Client請求的信息封裝到這個對象中
4、Servlet容器創(chuàng)建一個HttpResponse對象
5、Servlet容器調(diào)用HttpServlet對象的service方法,把HttpRequest對象與HttpResponse對象作為參數(shù)
傳給 HttpServlet對象
6、HttpServlet調(diào)用HttpRequest對象的有關(guān)方法,獲取Http請求信息
7、HttpServlet調(diào)用HttpResponse對象的有關(guān)方法,生成響應數(shù)據(jù)
8、Servlet容器把HttpServlet的響應結(jié)果傳給Web Client
對于Servlet容器(Tomcat)與HttpServlet是怎樣進行交互的呢,看下類圖

Servlet的框架是由兩個Java包組成的:javax.servlet與javax.servlet.http。在javax.servlet包中 定義了所有的Servlet類都必須實現(xiàn)或者擴展的通用接口和類。在javax.servlet.http包中定義了采用Http協(xié)議通信的 HttpServlet類。Servlet的框架的核心是javax.servlet.Servlet接口,所有的Servlet都必須實現(xiàn)這個接口。
在Servlet接口中定義了5個方法,
其中3個方法代表了Servlet的生命周期:
1、init方法:負責初始化Servlet對象。
2、service方法:負責響應客戶的請求。
3、destroy方法:當Servlet對象退出生命周期時,負責釋放占用的資源。
一、創(chuàng)建Servlet對象的時機
1、Servlet容器啟動時:讀取web.xml配置文件中的信息,構(gòu)造指定的Servlet對象,創(chuàng)建ServletConfig對象,同時將ServletConfig對象作為參數(shù)來調(diào)用Servlet對象的init方法。
2、在Servlet容器啟動后:客戶首次向Servlet發(fā)出請求,Servlet容器會判斷內(nèi)存中是否存在指定的Servlet對象,如果沒有則創(chuàng)建 它,然后根據(jù)客戶的請求創(chuàng)建HttpRequest、 HttpResponse對象,從而調(diào)用Servlet
對象的service方法。
3、Servlet的類文件被更新后,重新創(chuàng)建Servlet
Servlet容器在啟動時自動創(chuàng)建Servlet,這是由在web.xml文件中為Servlet設置的<load-on-startup>屬性決定
的。從中我們也能看到同一個類型的Servlet對象在Servlet容器中以單例的形式存在。
二、銷毀Servlet對象的時機
1、Servlet容器停止或者重新啟動:Servlet容器調(diào)用Servlet對象的destroy方法來釋放資源。以上所講的就是Servlet對象的生命周期。那么Servlet容器如何知道創(chuàng)建哪一個Servlet對象?
Servlet對象如何配置?實際上這些信息是通過讀取web.xml配置文件來實現(xiàn)的。
我們來看一下web.xml文件中的Servlet對象的配置節(jié)信息
-------------------------------------------
<servlet>
<servlet-name>action<servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
--------------------------------------------
下面對上面的配置節(jié)信息進行解析
servlet-name:Servlet對象的名稱
servlet-class:創(chuàng)建Servlet對象所要調(diào)用的類
param-name:參數(shù)名稱
param-value:參數(shù)值
load-on-startup:Servlet容器啟動時加載Servlet對象的順序
servlet-mapping/servlet-name:要與servlet中的servlet-name配置節(jié)內(nèi)容對應
url-pattern:客戶訪問的Servlet的相對URL路徑
當Servlet容器啟動的時候讀取<servlet>配置節(jié)信息,根據(jù)<servlet-class>配置節(jié)信息創(chuàng)建 Servlet對象,同時根據(jù)<init-param>配置節(jié)信息創(chuàng)建HttpServletConfig對象,然后執(zhí)行Servlet對象 的init方法,并且根據(jù)<load-on-startup>配置節(jié)信息來決定創(chuàng)建Servlet對象的順序,如果此配置節(jié)信息為負數(shù)或者沒 有配置,那么在Servlet容器啟動時,將不加載此Servlet對象。當客戶訪問Servlet容器時,Servlet容器根據(jù)客戶訪問的URL地 址,通過<servlet-mapping>配置節(jié)中的<url-pattern>配置節(jié)信息找到指定的Servlet對象,并 調(diào)用此Servlet對象的service方法。
為了驗證下,我新建了一個web app工程,新建一個Servlet,如下:
Java代碼

- package com.tdt.servlet;
-
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- public class TestServlet extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- this.doPost(request, response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
-
- response.setContentType("text/html");
- PrintWriter out = response.getWriter();
- out.println("Hello,this is a test");
-
- out.flush();
- out.close();
- }
-
- public void destroy() {
- System.err.println(getServletName()+"生命周期結(jié)束");;
- }
-
- public void init() throws ServletException {
- System.out.println(getServletName()+"執(zhí)行初始化");
- }
- }
當servlet被銷毀時會在控制臺上打印提示語句,不過我發(fā)現(xiàn)在tomcat中,只要不停止web容器,servlet是不會被銷毀的。有沒有什么方 法,當service方法執(zhí)行完畢就銷毀這個servlet呢,我問了下老師,他說寫一個監(jiān)聽器,不過我不知道怎么去實現(xiàn)它,如果有朋友知道實現(xiàn)的過程, 還請賜教。