一 、生命周期
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容器再將響應返回給客戶端。