servlet 學(xué)習(xí)筆記之二
——關(guān)于 Servlet 生命周期
寫這篇總結(jié)的時候,已經(jīng)辭職有好幾天了。去北京還沒有買到票, 4 月前,北京、上海、拉薩等地方的火車票都沒有了,還好我不急著走。
下面總結(jié)了 servlet 的生命周期。
Servlet 運行在 Servlet 容器中,其生命周期由容器來管理。 Servlet 的生命周期通過 Servlet 接口中 init ()、 service ()、 destroy ()方法來表示。
Servlet 的生命周期包含了下面 4 個階段。
(1) 加載和實例化
Servlet 容器負(fù)責(zé)加載和實例化 Servlet 。當(dāng) Servlet 容器啟動時,或者在容器檢查到需要這個 Servlet 來響應(yīng)一個請求時,創(chuàng)建 Servlet 實例。當(dāng) Servlet 容器啟動后,它必須要知道所需的 Servlet 類在什么位置, Servlet 容器可以從本地文件系統(tǒng)、遠(yuǎn)程文件系統(tǒng)或者其他網(wǎng)絡(luò)服務(wù)器中通過類加載器加載 Servlet 類,成功加載后,容器創(chuàng)建 Servlet 實例。因為容器是通過 Java 的反射 API 來創(chuàng)建 Servlet 實例,調(diào)用的是 Servlet 的默認(rèn)構(gòu)造函數(shù),也就是那個不帶參數(shù)的構(gòu)造函數(shù),所以我們在編寫 Servlet 類的時候,不應(yīng)該提供帶參數(shù)的構(gòu)造函數(shù)。——這也就是為什么 Servlet 類可以不寫構(gòu)造函數(shù)的原因。
(2) 初始化
在 Servlet 實例化之后,容器必須調(diào)用 Servlet 的 init ()方法初始化這個對象。初始化的目的是為了讓 Servlet 對象在處理客戶請求前完成一些初始化工作,如建立數(shù)據(jù)庫連接,獲取配置信息等。對于每一個 Servlet 實例, init ()方法只能被調(diào)用一次。在初始化期間, Servlet 實例可以使用容器為它準(zhǔn)備的 ServletConfit 對象從 web 應(yīng)用程序的配置信息(在 web.xml 中配置)中獲取初始化的參數(shù)信息。在初始化期間,如果發(fā)生錯誤, Servlet 實例可以拋出異常來通知容器。
(3) 請求處理
Servlet 容器調(diào)用 Servlet 的 service ()方法對請求進行處理。要注意的是,在 service ()方法調(diào)用之前, init ()方法必須成功執(zhí)行。在 service ()方法中, servlet 實例通過 ServletRequest 對象得到客戶端的相關(guān)信息和請求信息,在對請求進行處理后,調(diào)用 servletResponse 對象的方法設(shè)置響應(yīng)信息。
(4) 服務(wù)終止
當(dāng)容器檢測在一個 Servlet 實例應(yīng)該從服務(wù)中被移除的時候,容器就會調(diào)用實例的 destroy ()方法,以便讓該實例可以釋放它所使用的資源,保存數(shù)據(jù)到持久存儲設(shè)備中。當(dāng)需要釋放內(nèi)存或者容器關(guān)閉時,容器就會調(diào)用 Servlet 實例的 destroy ()方法。在調(diào)用 destroy ()方法后,容器會釋放這個 Servlet 實例,該實例隨后會被 java 的垃圾收集器回收。
在整個 Servlet 的生命周期過程中,創(chuàng)建 Servlet 實例、調(diào)用實例的 init ()和 destroy ()方法都只進行一次,當(dāng)初始化完成后, Servlet 容器會將該實例保存在內(nèi)存中,通過調(diào)用它的 service ()方法,為接收到的請求服務(wù)。