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公司為我們程式設計師提供了很多個不同的時刻。若在這個特殊的時刻執行特殊程式,這些程式是有位置編寫的。