1. 程式人生 > >Servlet和JSP的生命週期

Servlet和JSP的生命週期

一、Servlet生命週期

      Servlet是執行在Servlet容器(有時候也叫Servlet引擎,是web伺服器和應用程式伺服器的一部分,用於在傳送的請求和響應之上提供網路服務,解碼基於MIME的請求,格式化基於MIME的響應。常用的tomcat、jboss、weblogic都是Servlet容器)中的,其生命週期是由容器來管理。Servlet的生命週期通過java.servlet.Servlet介面中的init()、service()、和destroy()方法表示。Servlet的生命週期有四個階段:載入並例項化、初始化、請求處理、銷燬。

載入並例項化

      Servlet容器負責載入和例項化Servelt。當Servlet容器啟動時,或者在容器檢測到需要這個Servlet來響應第一個請求時,建立Servlet例項。當Servlet容器啟動後,Servlet通過類載入器來載入Servlet類,載入完成後再new一個Servlet物件來完成例項化。

初始化

      在Servlet例項化之後,容器將呼叫init()方法,並傳遞實現ServletConfig介面的物件。在init()方法中,Servlet可以部署描述符中讀取配置引數,或者執行任何其他一次性活動。在Servlet的整個生命週期類,init()方法只被呼叫一次。

請求處理

      當Servlet初始化後,容器就可以準備處理客戶機請求了。當容器收到對這一Servlet的請求,就呼叫Servlet的service()方法,並把請求和響應物件作為引數傳遞。當並行的請求到來時,多個service()方法能夠同時執行在獨立的執行緒中。通過分析ServletRequest或者HttpServletRequest物件,service()方法處理使用者的請求,並呼叫ServletResponse或者HttpServletResponse物件來響應。

銷燬

      一旦Servlet容器檢測到一個Servlet要被解除安裝,這可能是因為要回收資源或者因為它正在被關閉,容器會在所有Servlet的service()執行緒之後,呼叫Servlet的destroy()方法。然後,Servlet就可以進行無用儲存單元收集清理。這樣Servlet物件就被銷燬了。這四個階段共同決定了Servlet的生命週期。

二、Jsp生命週期

      Jsp頁必須轉換成Servlet,才能對請求進行服務,因此Jsp的底層完全是Servlet。這樣看來Jsp的生命週期就包括六個階段:轉換、編譯、載入並例項化、jspInit()呼叫(即初始化)、_jspService()呼叫(即請求處理)、jspDestroy()呼叫(即銷燬)。

轉換:就是web容器將Jsp檔案轉換成一個包含了Servlet類定義的java原始檔。

編譯:把在轉換階段建立的java原始檔編譯成類檔案。

Jsp生命週期其他的四個階段跟Servlet生命週期相同。

  現在來具體講一下:

     前一部分:

            1.建立:就是建立一個JSP原始檔

            2.部署:將JSP安裝到伺服器上(JaveEE伺服器或單機執行的JSP伺服器)

            3.解釋和編譯:將JSP原始檔解釋成java原始碼檔案,然後將該原始檔編譯成可在伺服器上執行的java類,這個類成為JSP頁面的實現類。(這一步可能在以後多個地方都會遇到)

     後一部分:

            1.裝載和例項化:前提是完成了前一部分的幾步得到了一個實現類。伺服器端會為JSP頁面查詢已有的實現類,如果沒有,就把這個實現類載入JVM中;載入JVM後就立刻產生一個該類的例項,或者在第一次請求時執行。

             2.初始化:初始化JSP頁面物件。如果你希望在初始化期間執行某些程式碼,那麼你可以向頁面中增加一個初始化方法(method),在初始化的時候就會呼叫該方法。

            3.請求處理:由頁面物件響應客戶端的請求。需要注意的是,單個物件例項將處理所有的請求。在執行完處理之後,伺服器將一個響應(response)返回給客戶端。這個響應完全是由HTML標籤和其他資料構成的,並不會把任何Java原始碼返回給客戶端。
              4.生命週期終止伺服器不再把客戶端的請求發給JSP。在所有的請求處理完成之後,會釋放掉這個類的所有例項。一般這種情況會發生在伺服器關閉的時候,但是也有其他的可能性,比如伺服器需要儲存資源、檢測到有JSP檔案更新,或者由於其他某些原因需要終止例項等情況。如果想讓程式碼執行清除工作,那麼可以實現一個方法,並且在這個類例項釋放之前呼叫該方法。