天天看點

jsp運作機制

jsp執行過程流程圖:

[img]http://shawnfree.iteye.com/upload/attachment/103207/3fc77d7a-bacb-3113-9ff3-619b76009f0f.gif[/img]

[b]1、jsp引擎[/b]

JSP引擎實際上要把JSP标簽、JSP頁中的Java代碼甚至連同靜态HTML内容都轉換為大塊的Java代碼。這些代碼塊被JSP引擎組織到使用者看不到的Java servlet中去,然後servlet自動把JVM(java虛拟機)編譯成Java位元組碼。這樣,當網站的通路者請求一個JSP頁時,在他不知道的情況下,一個已經生成的、預編譯過的servlet實際上将完成所有的工作。非常隐蔽-而又高效。因為servlet是編譯過的,是以網頁中的JSP代碼不需要在每次請求該頁時被解釋一遍。JSP引擎隻需在servlet代碼最後被修改後編譯一次,然後這個編譯過的servlet就可以被執行了。由于是JSP引擎自動生成并編譯servlet,不用程式員動手編譯代碼,是以JSP能帶給你高效的性能和快速開發所需的靈活性。

[b]2、web容器和servlet容器[/b]

servlet容器的主要任務是管理servlet的生命周期。web容器更準确的說應該叫web伺服器,它是來管理和部署web應用的。還有一種伺服器叫做應用伺服器,它的功能比web伺服器要強大的多,因為它可以部署EJB應用,可以實作容器管理的事務,一般的應用伺服器有weblogic和websphere等,它們都是商業伺服器,功能強大但都是收費的。web容器最典型的就是tomcat了,Tomcat是web容器也是servlet容器

[b]2、jsp工作原理[/b][size=x-small]當web容器(tomcat、jboss等等)接收到使用者的第一個jsp頁面請求時,jsp引擎将這個jsp頁面轉換為java源代碼(servlet類),在轉換過程中,如果發現jsp檔案有任何的文法錯誤,轉換過程将終止,并向伺服器和用戶端輸出錯誤資訊,如果轉換成功,然後jsp引擎用javac編譯java源代碼生成class檔案,然後web容器加載class檔案并從此建立一個新的servlet對象進行執行個體化,當 Servlet 類執行個體化後,容器加載 jsinit,以通知 servlet 它已進入服務行列。init 方法必須被加載,Servelt 才能接收和請求。假如要載入資料庫驅動程式、初始化一些值等等,程式員可以重寫這個方法。在其他情況下,這個方法一般為空,jspInit()方法在servlet的生命周期中隻被執行一次。然後jspService()方法被調用來處理用戶端的請求。容器建立一個響應文檔,次文檔發送給使用者,如幹時間後,使用者再次通路這個j請求這個jsp時,容器回再次建立響應一個文檔,直到容器解除安裝了這個class檔案,當使用者解除安裝了這個class檔案後,再次通路時,jsp引擎并不重新轉換和編譯這個jsp檔案,而是對它進行重新初始化,并建立一個響應文檔,傳回給用戶端。對每一個請求,web容器建立一個新的線程來處理該請求。如果有多個用戶端同時請求該JSP檔案,則JSP引擎會建立多個線程。每個用戶端請求對應一個線程。以多線程方式執行可大大降低對系統的資源需求,提高系統的并發量及響應時間.但應該注意多線程的程式設計限制,由于該servlet始終駐于記憶體,是以響應是非常快的。如果.jsp檔案被修改了,伺服器将根據設定決定是否對該檔案重新編譯,如果需要重新編譯,則将編譯結果取代記憶體中的servlet,并繼續上述處理過程。如果在任何時候如果由于系統資源不足的原因,web容器将以某種不确定的方式将servlet從記憶體中移去。當這種情況發生時jspDestroy()方法首先被調用, 然後servlet執行個體便被标記加入"垃圾收集"處理。[/size]

[b]3、jsp腳本與聲明的差異[/b]

二者的差異在于作用域和生存期,

(1)、jsp聲明中建立的名字有類範圍的作用域和生存期

(2)、jsp腳本中建立的名字有局限于方法的作用域和生存期。

二者的作用域就像是java中在類中定義一個屬性A和在類的方法中定義一個屬性B,

類中不能引用屬性B,但是在方法中可以引用屬性A,

二者的生存期:

jsp聲明,例如:<%!int count=100;%><%=count++%>

腳本中的變量生存期存在于第一個使用者延續到第二個使用者。。。。,如果第一個使用者第一次通路時100,第二個使用者通路就101,第三個使用者通路時102,以此類推。。。如果伺服器停止而重新啟動後,則count值就傳回到100,

jsp腳本,例如:<%int count=100;%><%=count++%>

腳本中的變量生存期存在于每個使用者的通路期間,是以沒有使用者通路都是100

[color=red]無論聲明和腳本放置的位置不同,jsp容器都是首先進行初始化聲明,再執行腳本的。[/color]

[b]總結:[/b]

(1)、不能在腳本中定義方法,但可以再jsp聲明中定義自己的方法,因為腳本程式是局限于jspService方法中的,如果在jspservice方法中再次定義方法是不允許的。

(2)、不能在jso聲明中使用out等隐藏對象,因為out等隐藏對象,是作用域jspservice方法中定義的。

(3)、腳本中定義變量,不能在jsp聲明中引用此變量。

(4)、如果變量定義在方法中,則不能在方法之前使用此變量。