1. 程式人生 > >Servlet的生命週期 (一)

Servlet的生命週期 (一)

package com.xxxx.java;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class Servletlife implements Servlet {
      
	/*建立一個無參的建構函式*/
	public Servletlife(){
		System.out.println("Servletlitf's Construct  methord execute");
		
	}
		
	@Override
	public void destroy() {
		System.out.println("Servletlitf's destroy  methord execute");
	}

	@Override
	public ServletConfig getServletConfig() {
		//System.out.println("Servletlitf's getServletConfig  methor execute");
		return null;
	}

	@Override
	public String getServletInfo() {
		//System.out.println("Servletlitf's getServletInfo  methor execute");
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		System.out.println("Servletlitf's init  methor execute");

	}

	@Override
	public void service(ServletRequest request, ServletResponse response)
			throws ServletException, IOException {
		System.out.println("Servletlitf's service  methor execute");

	}

}

 

關於Servlet物件的生命週期
    1、什麼是生命週期
       生命週期表示一個java物件從最初被建立到最終被銷燬,經歷的所有過程。
    2、Servlet物件的生命週期是誰來管理的?程式設計師可以干涉嗎?
       Servlet物件的生命週期,javaweb程式設計師是無權干涉的,包括Servlet物件的相關方法的呼叫,javaweb程式設計師也是無權干涉的。
       Servlet物件從最初的建立,方法的呼叫,以及物件的銷燬,整個過程,是由web容器管理的。
       Web Container管理Servlet物件的生命週期。
    3、"預設情況下",Servlet物件在WEB伺服器啟動階段不會被例項化。
    4、描述Servlet物件的生命週期
       1) 使用者在瀏覽器位址列上輸入URL:http://localhost:8080/prj-servlet/testLifeCycle
       2) web容器擷取請求路徑: /prj-serlet-03/testLifeCycle
       3) web容器在容器上下文中找請求路徑 /prj-servlet-03/testLifeCycle對應的Servlet物件
       4) 若沒有找對應的Servlet物件
          4.1)通過web.xml檔案中相關的配置資訊,得到請求路徑/testLifeCycle對應的Servlet完整的類名
          4.2)通過反射機制,呼叫Servlet類的無參構造方法完成Servlet物件的例項化
          4.3)web容器呼叫Servlet物件的init方法完成初始化操作
          4.4) web容器呼叫Servlet物件的service方法提供服務
       5)若找到對應的Servlet物件
          5.1)web容器直接呼叫Servlet物件的Service方法提供服務
       6) web容器關閉的時候/webapp重新部署的時候該Servlet物件長時間沒有使用者再次訪問的時候,web容器會將該Servlet物件銷燬,在銷燬該物件之前,web容器會呼叫Servlet物件的destroy方法,完成銷燬之前的準備。
    5、總結:
       5.1 Servlet類的構造方法只執行一次
       5.2 Servlet物件的init方法只執行一次
       5.3 Servlet物件的service方法,只要使用者請求一次,則執行一次
       5.4 Servlet物件的destroy方法只執行一次
    6、注意:
       init方法執行的時候,Servlet物件已經被建立好了。
       destory方法執行的時候,Servlet物件還沒有被銷燬,即將被銷燬
    7、Servlet物件是單例,但是不符合單例模式,只能稱為偽單例。真單例的構造方法是私有化的,Tomcat伺服器是支援多執行緒的。所以Sservlet物件在單例項多執行緒的環境下執行的。那麼Servlet物件中若有例項變數,並且例項變數涉及到修改操作,那麼這個Servlet物件一定會存線上程安全問題,不建議在Servlet物件中使用例項變數,儘量使用區域性變數

   8、若希望在web伺服器啟動階段例項化Servlet物件,需要在web.xml檔案中進行相關的配置,例如:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
     <servlet-name>testlife0</servlet-name>
     <servlet-class>com.xxx.java.Servletlife</servlet-class>
     <!-- 在伺服器啟動階段建立Servlet物件 -->
     <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>testlife0</servlet-name>    
      <url-pattern>/Servletlife</url-pattern>
  </servlet-mapping>
  <servlet>
     <servlet-name>testlife1</servlet-name>
     <servlet-class>com.xxx.java.WelcomeServlet</servlet-class>
     <!-- 在伺服器啟動階段建立Servlet物件 -->
     <!--這裡的1和0是有差別的,越靠前越先執行-->
     <load-on-startup>0</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>testlife1</servlet-name>    
      <url-pattern>/WelcomeServlet</url-pattern>
  </servlet-mapping>
</web-app>

 

9、Servlet物件例項化之後,這個Servlet物件被儲存到哪裡了?
        大多數的WEB容器都是該Servlet物件以及對應的url-pattern儲存到Map集合中了:
        在WEB容器中有這樣一個Map集合
          Map<String, Servlet> 集合
          key            value
          ----------------------
          /login         LoginServlet物件引用
          /delete        DeleteServlet物件引用
          /save          SaveServlet物件引用

        ........
    10、伺服器在啟動的時候就會解析各個webapp的web.xml檔案,做了什麼?
        將web.xml檔案中的url-pattern和對應的Servlet完整類名儲存到Map集合中:
        在WEB容器中有這樣一個Map集合
        Map<String, String>  集合
        key          value
        --------------------------
        /login       com.xxx.javaweb.servlet.LoginServlet
        /delete      com.xxx.javaweb.servlet.DeleteServlet 

    ......

11、Servlet介面中的這些方法中編寫什麼程式碼?什麼時候使用這些方法?
        1)無引數構造方法【以後就不需要再考慮構造函數了,儘量別動建構函式】
        2)init方法
        以上兩個方法執行時間幾乎是相同的,執行次數都是一次,構造方法執行的時候物件正在建立,init方法執行的時候物件已經建立:
           若系統要求在物件建立時刻執行一段特殊的程式,這段程式儘量些到init方法中。為什麼不建議寫在建構函式中呢?存在風險!
             當啊程式設計師編寫構造方法的時候,可能會導致i無引數構造方法的不存在。
             一個類不編寫任何建構函式,預設有一個無引數的構造方法,但是一旦編寫一個有引數的構造方法之後,系統則不再提供無引數建構函式。
             Servlet中的init方法是SUN公司為javaweb程式設計師專門提供的一個初始化時刻,若希望在初始化時刻執行一段特殊的程式,這個程式可以編寫到init方法,將來回自動被呼叫。
        3)service方法
            這個方法是必然重寫的,因為這個方法需要完成業務邏輯的處理,請求的處理,以及完成響應。
            而且這個方法中的程式碼是最有價值的。
            也是最難寫的,因為最難編寫的就是業務程式碼了。
        4)destroy方法
            這個方法也是SUN公司為javaweb程式設計師提供的一個特殊時刻,這個特殊的時刻被稱為物件銷燬時刻,
            若希望在銷燬時刻執行一段特殊的程式碼,需要將這段程式碼編寫到destroy方法,自動被容器呼叫。
        回顧:
            類載入時刻執行程式,程式碼寫到哪裡?
                編寫到靜態程式碼塊中。
        結論:
            sun公司為我們程式設計師提供了很多個不同的時刻。若在這個特殊的時刻執行特殊程式,這些程式是有位置編寫的。