servlet规范定义的Servlet生命周期
生活随笔
收集整理的這篇文章主要介紹了
servlet规范定义的Servlet生命周期
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
servlet有良好的生存期的定義,包括如何加載、實(shí)例化、初始化、處理客戶端請求以及如何被移除。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達(dá)。
1、加載和實(shí)例化
容器負(fù)責(zé)加載和實(shí)例化一個servlet。實(shí)例化和加載可以發(fā)生在引擎啟動的時候,也可以推遲到容器需要該servlet為客戶請求服務(wù)的時候。
首先容器必須先定位servlet類,在必要的情況下,容器使用通常的Java類加載工具加載該servlet,可能是從本機(jī)文件系統(tǒng),也可以是從遠(yuǎn)程 文件系統(tǒng)甚至其它的網(wǎng)絡(luò)服務(wù)。容器加載servlet類以后,它會實(shí)例化該類的一個實(shí)例。需要注意的是可能會實(shí)例化多個實(shí)例,例如一個servlet類因 為有不同的初始參數(shù)而有多個定義,或者servlet實(shí)現(xiàn)SingleThreadModel而導(dǎo)致容器為之生成一個實(shí)例池。
2、初始化
servlet加載并實(shí)例化后,容器必須在它能夠處理客戶端請求前初始化它。初始化的過程主要是讀取永久的配置信息,昂貴資源(例如JDBC連接)以及 其它僅僅需要執(zhí)行一次的任務(wù)。通過調(diào)用它的init方法并給它傳遞唯一的一個(每個servlet定義一個)ServletConfig對象完成這個過 程。給它傳遞的這個配置對象允許servlet訪問容器的配置信息中的名稱-值對(name-value)初始化參數(shù)。這個配置對象同時給servlet 提供了訪問實(shí)現(xiàn)了ServletContext接口的具體對象的方法,該對象描述了servlet的運(yùn)行環(huán)境。
2.1初始化的錯誤處理
在初始化期間,servlet實(shí)例可能通過拋出UnavailableException 或者 ServletException異常表明它不能進(jìn)行有效服務(wù)。如果一個servlet拋出一個這樣的異常,它將不會被置入有效服務(wù)并且應(yīng)該被容器立即釋 放。在此情況下destroy方法不會被調(diào)用因?yàn)槌跏蓟瘺]有成功完成。在失敗的實(shí)例被釋放后,容器可能在任何時候?qū)嵗粋€新的實(shí)例,對這個規(guī)則的唯一例 外是如果失敗的servlet拋出的異常是UnavailableException并且該異常指出了最小的無效時間,那么容器就會至少等待該時間指明的 時限才會重新試圖創(chuàng)建一個新的實(shí)例。
2.2、工具因素
當(dāng)工具(注:根據(jù)筆者的理解,這個工具可能是應(yīng)用服務(wù)器的 某些檢查工具,通常是驗(yàn)證應(yīng)用的合法性和完整性)加載和內(nèi)省(introspect)一個web應(yīng)用時,它可能加載和內(nèi)省該應(yīng)用中的類,這個行為將觸發(fā)那 些類的靜態(tài)初始方法被執(zhí)行,因此,開發(fā)者不能假定只要當(dāng)servlet的init方法被調(diào)用后它才處于活動容器運(yùn)行狀態(tài)(active container runtime)。作為一個例子,這意味著servlet不能在它的靜態(tài)(類)初始化方法被調(diào)用時試圖建立數(shù)據(jù)庫連接或者連接EJB容器。
3、處理請求
在servlet被適當(dāng)?shù)爻跏蓟?#xff0c;容器就可以使用它去處理請求了。每一個請求由ServletRequest類型的對象代表,而servlet使用 ServletResponse回應(yīng)該請求。這些對象被作為service方法的參數(shù)傳遞給servlet。在HTTP請求的情況下,容器必須提供代表請 求和回應(yīng)的HttpServletRequest和HttpServletResponse的具體實(shí)現(xiàn)。需要注意的是容器可能會創(chuàng)建一個servlet實(shí) 例并將之放入等待服務(wù)的狀態(tài),但是這個實(shí)例在它的生存期中可能根本沒有處理過任何請求。
3.1、多線程問題
容器 可能同時將多個客戶端的請求發(fā)送給一個實(shí)例的service方法,這也就意味著開發(fā)者必須確保編寫的servlet可以處理并發(fā)問題。如果開發(fā)者想防止這 種缺省的行為,那么他可以讓他編寫的servlet實(shí)現(xiàn)SingleThreadModel。實(shí)現(xiàn)這個類可以保證一次只會有一個線程在執(zhí)行service 方法并且一次性執(zhí)行完。容器可以通過將請求排隊(duì)或者維護(hù)一個servlet實(shí)例池滿足這一點(diǎn)。如果servlet是分布式應(yīng)用的一部分,那么,那么容器可 能在該應(yīng)用分布的每個JVM中都維護(hù)一個實(shí)例池。如果開發(fā)者使用synchronized關(guān)鍵字定義service方法(或者是doGet和 doPost),容器將排隊(duì)處理請求,這是由底層的java運(yùn)行時系統(tǒng)要求的。我們強(qiáng)烈推薦開發(fā)者不要同步service方法或者HTTPServlet 的諸如doGet和doPost這樣的服務(wù)方法。
3.2、處理請求中的異常
servlet在對請求進(jìn)行服務(wù)的時 候有可能拋出ServletException或者UnavailableException異常。ServletException表明在處理請求的過 程中發(fā)生了錯誤容器應(yīng)該使用合適的方法清除該請求。UnavailableException表明servlet不能對請求進(jìn)行處理,可能是暫時的,也可 能是永久的。如果UnavailableException指明是永久性的,那么容器必須將servlet從服務(wù)中移除,調(diào)用它的destroy方法并釋 放它的實(shí)例。如果指明是暫時的,那么容器可以選擇在異常信息里面指明的這個暫時無法服務(wù)的時間段里面不向它發(fā)送任何請求。在這個時間段里面被被拒絕的請求 必須使用SERVICE_UNAVAILABLE (503)返回狀態(tài)進(jìn)行響應(yīng)并且應(yīng)該攜帶稍后重試(Retry-After)的響應(yīng)頭表明不能服務(wù)只是暫時的。容器也可以選擇不對暫時性和永久性的不可用 進(jìn)行區(qū)分而全部當(dāng)作永久性的并移除拋出異常的servlet。
3.3線程安全
開發(fā)者應(yīng)該注意容器實(shí)現(xiàn)的請求和響 應(yīng)對象(注:即容器實(shí)現(xiàn)的HttpServletRequest和HttpServletResponese)沒有被保證是線程安全的,這就意味著他們只 能在請求處理線程的范圍內(nèi)被使用,這些對象不能被其它執(zhí)行線程所引用,因?yàn)橐玫男袨槭遣淮_定的。
4、服務(wù)結(jié)束
容器沒有被要求將一個加載的servlet保存多長時間,因此一個servlet實(shí)例可能只在容器中存活了幾毫秒,當(dāng)然也可能是其它更長的任意時間(但是 肯定會短于容器的生存期)當(dāng)容器決定將之移除時(原因可能是保存內(nèi)存資源或者自己被關(guān)閉),那么它必須允許servlet釋放它正在使用的任何資源并保存 任何永久狀態(tài)(這個過程通過調(diào)用destroy方法達(dá)到)。容器在能夠調(diào)用destroy方法前,它必須允許那些正在service方法中執(zhí)行的線程執(zhí)行 完或者在服務(wù)器定義的一段時間內(nèi)執(zhí)行(這個時間段在容器調(diào)用destroy之前)。一旦destroy方法被調(diào)用,容器就不會再向該實(shí)例發(fā)送任何請求。如 果容器需要再使用該servlet,它必須創(chuàng)建新的實(shí)例。destroy方法完成后,容器必須釋放servlet實(shí)例以便它能夠被垃圾回收。
1、加載和實(shí)例化
容器負(fù)責(zé)加載和實(shí)例化一個servlet。實(shí)例化和加載可以發(fā)生在引擎啟動的時候,也可以推遲到容器需要該servlet為客戶請求服務(wù)的時候。
首先容器必須先定位servlet類,在必要的情況下,容器使用通常的Java類加載工具加載該servlet,可能是從本機(jī)文件系統(tǒng),也可以是從遠(yuǎn)程 文件系統(tǒng)甚至其它的網(wǎng)絡(luò)服務(wù)。容器加載servlet類以后,它會實(shí)例化該類的一個實(shí)例。需要注意的是可能會實(shí)例化多個實(shí)例,例如一個servlet類因 為有不同的初始參數(shù)而有多個定義,或者servlet實(shí)現(xiàn)SingleThreadModel而導(dǎo)致容器為之生成一個實(shí)例池。
2、初始化
servlet加載并實(shí)例化后,容器必須在它能夠處理客戶端請求前初始化它。初始化的過程主要是讀取永久的配置信息,昂貴資源(例如JDBC連接)以及 其它僅僅需要執(zhí)行一次的任務(wù)。通過調(diào)用它的init方法并給它傳遞唯一的一個(每個servlet定義一個)ServletConfig對象完成這個過 程。給它傳遞的這個配置對象允許servlet訪問容器的配置信息中的名稱-值對(name-value)初始化參數(shù)。這個配置對象同時給servlet 提供了訪問實(shí)現(xiàn)了ServletContext接口的具體對象的方法,該對象描述了servlet的運(yùn)行環(huán)境。
2.1初始化的錯誤處理
在初始化期間,servlet實(shí)例可能通過拋出UnavailableException 或者 ServletException異常表明它不能進(jìn)行有效服務(wù)。如果一個servlet拋出一個這樣的異常,它將不會被置入有效服務(wù)并且應(yīng)該被容器立即釋 放。在此情況下destroy方法不會被調(diào)用因?yàn)槌跏蓟瘺]有成功完成。在失敗的實(shí)例被釋放后,容器可能在任何時候?qū)嵗粋€新的實(shí)例,對這個規(guī)則的唯一例 外是如果失敗的servlet拋出的異常是UnavailableException并且該異常指出了最小的無效時間,那么容器就會至少等待該時間指明的 時限才會重新試圖創(chuàng)建一個新的實(shí)例。
2.2、工具因素
當(dāng)工具(注:根據(jù)筆者的理解,這個工具可能是應(yīng)用服務(wù)器的 某些檢查工具,通常是驗(yàn)證應(yīng)用的合法性和完整性)加載和內(nèi)省(introspect)一個web應(yīng)用時,它可能加載和內(nèi)省該應(yīng)用中的類,這個行為將觸發(fā)那 些類的靜態(tài)初始方法被執(zhí)行,因此,開發(fā)者不能假定只要當(dāng)servlet的init方法被調(diào)用后它才處于活動容器運(yùn)行狀態(tài)(active container runtime)。作為一個例子,這意味著servlet不能在它的靜態(tài)(類)初始化方法被調(diào)用時試圖建立數(shù)據(jù)庫連接或者連接EJB容器。
3、處理請求
在servlet被適當(dāng)?shù)爻跏蓟?#xff0c;容器就可以使用它去處理請求了。每一個請求由ServletRequest類型的對象代表,而servlet使用 ServletResponse回應(yīng)該請求。這些對象被作為service方法的參數(shù)傳遞給servlet。在HTTP請求的情況下,容器必須提供代表請 求和回應(yīng)的HttpServletRequest和HttpServletResponse的具體實(shí)現(xiàn)。需要注意的是容器可能會創(chuàng)建一個servlet實(shí) 例并將之放入等待服務(wù)的狀態(tài),但是這個實(shí)例在它的生存期中可能根本沒有處理過任何請求。
3.1、多線程問題
容器 可能同時將多個客戶端的請求發(fā)送給一個實(shí)例的service方法,這也就意味著開發(fā)者必須確保編寫的servlet可以處理并發(fā)問題。如果開發(fā)者想防止這 種缺省的行為,那么他可以讓他編寫的servlet實(shí)現(xiàn)SingleThreadModel。實(shí)現(xiàn)這個類可以保證一次只會有一個線程在執(zhí)行service 方法并且一次性執(zhí)行完。容器可以通過將請求排隊(duì)或者維護(hù)一個servlet實(shí)例池滿足這一點(diǎn)。如果servlet是分布式應(yīng)用的一部分,那么,那么容器可 能在該應(yīng)用分布的每個JVM中都維護(hù)一個實(shí)例池。如果開發(fā)者使用synchronized關(guān)鍵字定義service方法(或者是doGet和 doPost),容器將排隊(duì)處理請求,這是由底層的java運(yùn)行時系統(tǒng)要求的。我們強(qiáng)烈推薦開發(fā)者不要同步service方法或者HTTPServlet 的諸如doGet和doPost這樣的服務(wù)方法。
3.2、處理請求中的異常
servlet在對請求進(jìn)行服務(wù)的時 候有可能拋出ServletException或者UnavailableException異常。ServletException表明在處理請求的過 程中發(fā)生了錯誤容器應(yīng)該使用合適的方法清除該請求。UnavailableException表明servlet不能對請求進(jìn)行處理,可能是暫時的,也可 能是永久的。如果UnavailableException指明是永久性的,那么容器必須將servlet從服務(wù)中移除,調(diào)用它的destroy方法并釋 放它的實(shí)例。如果指明是暫時的,那么容器可以選擇在異常信息里面指明的這個暫時無法服務(wù)的時間段里面不向它發(fā)送任何請求。在這個時間段里面被被拒絕的請求 必須使用SERVICE_UNAVAILABLE (503)返回狀態(tài)進(jìn)行響應(yīng)并且應(yīng)該攜帶稍后重試(Retry-After)的響應(yīng)頭表明不能服務(wù)只是暫時的。容器也可以選擇不對暫時性和永久性的不可用 進(jìn)行區(qū)分而全部當(dāng)作永久性的并移除拋出異常的servlet。
3.3線程安全
開發(fā)者應(yīng)該注意容器實(shí)現(xiàn)的請求和響 應(yīng)對象(注:即容器實(shí)現(xiàn)的HttpServletRequest和HttpServletResponese)沒有被保證是線程安全的,這就意味著他們只 能在請求處理線程的范圍內(nèi)被使用,這些對象不能被其它執(zhí)行線程所引用,因?yàn)橐玫男袨槭遣淮_定的。
4、服務(wù)結(jié)束
容器沒有被要求將一個加載的servlet保存多長時間,因此一個servlet實(shí)例可能只在容器中存活了幾毫秒,當(dāng)然也可能是其它更長的任意時間(但是 肯定會短于容器的生存期)當(dāng)容器決定將之移除時(原因可能是保存內(nèi)存資源或者自己被關(guān)閉),那么它必須允許servlet釋放它正在使用的任何資源并保存 任何永久狀態(tài)(這個過程通過調(diào)用destroy方法達(dá)到)。容器在能夠調(diào)用destroy方法前,它必須允許那些正在service方法中執(zhí)行的線程執(zhí)行 完或者在服務(wù)器定義的一段時間內(nèi)執(zhí)行(這個時間段在容器調(diào)用destroy之前)。一旦destroy方法被調(diào)用,容器就不會再向該實(shí)例發(fā)送任何請求。如 果容器需要再使用該servlet,它必須創(chuàng)建新的實(shí)例。destroy方法完成后,容器必須釋放servlet實(shí)例以便它能夠被垃圾回收。
轉(zhuǎn)載于:https://www.cnblogs.com/nobel1984/archive/2008/11/09/1330119.html
總結(jié)
以上是生活随笔為你收集整理的servlet规范定义的Servlet生命周期的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: helm原理
- 下一篇: Intellij IDEA关闭 Buil