1. 程式人生 > >servlet生命週期和執行流程

servlet生命週期和執行流程

一 、生命週期

servlet 宣告週期可以分四個階段:

  • 類裝載過程
  • init() 初始化過程
  • service() 服務過程,選擇doGet \ doPost
  • destroy() 銷燬過程

servlet介面如下

public interface Servlet {
    void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); void destroy(); }

1、建立servlet例項

時期:預設是第一個請求該servlet的時候就初始化此servlet,該servlet例項便一直存在,直到長

​ 時間不呼叫、伺服器關閉才銷燬 或者 類檔案更新後重新載入 。也可手動設定:在伺服器

​ 啟動時便載入此servlet 。

<servlet>
	<servlet-name>Xxx</servlet-name>
     <servlet-class>com.lingz.Xxx</servlet-class>
     <load-on-startup>1</load-on-startup> </servlet>

2、init()初始化

​ servlet例項一創建出來,便呼叫init(ServletConfig var1) 進行初始化, 其中的ServletConfig引數物件攜帶了該servlet的配置資訊,比如初始化引數,此ServletConfig引數由伺服器建立。

(1)那麼,如何配置 servlet的初始化引數?

<servlet>
	<servlet-name>Xxx</servlet-name>
	<servlet-class>com.lingz.Xxx</servlet-class>
  	<!--兩個自定義的初始化引數--> <init-param> <param-name>value1</param-name> <param-value>key1</param-value> </init-param>   <init-param> <param-name>value2</param-name> <param-value>key2</param-value> </init-param> </servlet>

​ 通過這種配置方式,就不需要在Servlet中新增、修改,直接修改xml檔案即可。

(2)如何讀取上面的引數呢?

​ 通過 ServletConfig類提供的 getInitParameter(String name) 獲取初始化引數

public interface ServletConfig {
    String getServletName();

    ServletContext getServletContext(); String getInitParameter(String var1); Enumeration<String> getInitParameterNames(); }

(3)init(ServletConfig var1) 在Servlet生命週期中,只執行一次。並且是單執行緒執行,不需要擔心多執行緒安全。

3、service() 服務過程

(1)請求發到對應的Servlet,Servlet呼叫service(),service() 根據請求呼叫doGet \ doPost

​ service方法是處理業務的核心。

(2)service() 與多執行緒

​ servlet 是單例的,當多個請求請求同一個servlet時,需要主要注意執行緒安全,不過也存在可以不必考慮執行緒安全的情況。

①執行緒安全情況
  • 如果service()方法沒有訪問Servlet的成員變數也沒有訪問全域性的資源比如靜態變數、檔案、資料庫連線等,而是隻使用了當前執行緒自己的資源,比如非指向全域性資源的臨時變數、request和response物件等。該方法本身就是執行緒安全的,不必進行任何的同步控制。
  • 如果service()方法訪問了Servlet的成員變數,但是對該變數的操作是隻讀操作,該方法本身就是執行緒安全的,不必進行任何的同步控制。
②執行緒不安全情況
  • 如果service()方法訪問了全域性的靜態變數,如果同一時刻系統中也可能有其它執行緒訪問該靜態變數,如果既有讀也有寫的操作,通常需要加上同步控制語句。
  • 如果service()方法訪問了全域性的資源,比如檔案、資料庫連線等,通常需要加上同步控制語句。

4 、destroy()銷燬

​ 當web伺服器認為此servlet沒有存在的必要、類重新載入、伺服器關閉、長時間未被訪問,則可以從記憶體中銷燬。而回收該Servlet記憶體前必須呼叫destroy(),web伺服器保證該方法被呼叫時已經結束了請求呼叫的service()或等待剩餘的請求執行完,並且不會再接收請求。當全部請求處理完並響應後,即可destroy() 並進行記憶體回收

 

二、執行流程

通過上面的描述,其實我們對執行流程已有了大體的認知:

1. 根據時機,Web容器載入對應的Servlet類,載入後進行init()初始化。
 - 設定了容器啟動時初始化
 - 請求第一次請求此Servlet時初始化
 - Servlet類檔案被更新後,重新裝載Servlet
2. 接收到請求,容器根據配置將請求交給對應的Servlet,同時建立HttpServletRequest 和 HttpServletResponse 物件,一併交給Servlet。
3. 在service()中根據HttpServletRequest得請求型別等資訊,呼叫doGet\doPost 進行業務處理。
4. 處理後通過HttpServletResponse獲得相應資訊,返回給Web容器。
5. Web容器再將響應返回給客戶端。

參考:https://www.cnblogs.com/Wonghy/p/5542277.html