深入淺出Web容器-Tomcat原始碼分析.ppt
《深入淺出Web容器-Tomcat原始碼分析.ppt》由會員分享,可在線閱讀,更多相關(guān)《深入淺出Web容器-Tomcat原始碼分析.ppt(52頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、深入淺出 Web 容器,Tomcat 原始碼分析,林信良 資深技術(shù)顧問 http://openhome.cc caterpillaropenhome.cc,主題,Web 容器與 Servlet 從 HTTP 請求到 service() 在service()的前後 從 JSP 到 Servlet 自訂標籤處理,Web 容器與 Servlet,Web 容器與 Servlet,容器(Container)裝水的嗎?,別鬧了容器是個 Java 應(yīng)用程式,介於 Servlet 與Web 伺服器之間,我管很多事,你不用認識 Web 伺服器,你只要認得我!,Web 容器與 Servlet,管很多事?哪些事啊?
2、,你沒想過 HTTP 那些麻煩的東西是怎麼變成 Java 物件的嗎?你以為 Servlet 中的 Request 與 Response 是怎麼來的?,Web 容器與 Servlet,看起來好像很複雜?,要了解我的內(nèi)在確實不容易,那先從簡單的開始好了,知道一個Servlet是實作 Servlet 介面嗎?,..,來個簡化版的,if(servlets.get(servletName) == null) servlet = (Servlet) myClass.newInstance(); servlets.put(servletName, servlet); servlet.init(
3、new Config(myClass)); else servlet = servlets.get(servletName); servlet.service( (ServletRequest) requestFacade, (ServletResponse) responseFacade);,public void destroy() for(Servlet servlet : servlets.values()) servlet.destroy(); ,至少你要知道init()、service()與destroy(),Web 容器與 Servlet
4、,你管的就是這些?,當然更多!不只ServletRequest、ServletResponse、ServletConfig、Servlet這些,對了!這個範例改寫自這邊 ,從 HTTP 請求到 service(),我實際上很強壯的啦.XD,從 HTTP 請求到 service(),當請求來到時是 Worker Thread 模式,public void run() while (running) // Allocate a new worker thread MasterSlaveWorkerThread workerThread = createWorkerThread();
5、 // Accept the next incoming connection from the server socket ... Socket socket = acceptSocket(); workerThread.assign(socket); .. ,沒原始碼沒真相...XD,採用Thread Pool...XD,,從 HTTP 請求到 service(),,接下來快轉(zhuǎn)一下來到了Http11Processor,我應(yīng)該說過我負責建立Request與Response物件吧這個類別剖析HTTP並設(shè)定Request、Response,從 HTTP 請求到 service()
6、,,在Http11Processor的process()中,呼叫 adapter.service(),adapter.service(request, response);,再來的話這邊的request、response會被org.apache.catalina.connector套件中的Request、Response包裹起來...,WHY?,從 HTTP 請求到 service(),package org.apache.catalina.connector; public class Request implements HttpServletRequest ,package org.
7、apache.catalina.connector; public class Response implements HttpServletResponse ,從 HTTP 請求到 service(),再快轉(zhuǎn)一下Request與Response送到容器ContainerBase,最後來到StandardWrapper 你要注意一下loadServlet()方法 回憶 Servlet第一次被請求時會被載入 建立ServletConfig 執(zhí)行init() 呼叫service(),public class StandardWrapper extends ContainerBase im
8、plements ServletConfig, Wrapper, NotificationEmitter ,if (classLoader != null) classClass = classLoader.loadClass(actualClass); else classClass = Class.forName(actualClass); ... // Instantiate and initialize an instance of the servlet class try servlet = (Servlet) classClass.newInst
9、ance(); ... try servlet.init(facade); servlet.service(req, res); ,facade 參考至實作 ServletConfig 的實例 protected StandardWrapperFacade facade = new StandardWrapperFacade(this);,從 HTTP 請求到 service(),SingleThreadModel 怎麼實現(xiàn)?你可以自己找找看,喵好複雜Orz,已經(jīng)省略了很多細節(jié)了你可以用這個流程來研究一些更深入的XD,,在service()的前後,在service()的前後,
10、你知道在Servlet前可以套用Filter吧!,好像是有這麼一回事XD,實現(xiàn)了Interceptor Filter模式,當我們又來到Servlet,在service()的前後,GenericServlet類別 還實作了ServletConfig介面,將容器呼叫init()方法時所傳入的ServletConfig實例封裝起來 service()方法直接標示為abstract而沒有任何的實作 HTTP相關(guān)服務(wù)流程定義在HttpServlet的service()方法,在service()的前後,protected void service(HttpServletRequest req,
11、 HttpServletResponse resp) throws ServletException, IOException String method = req.getMethod(); // 取得請求的方法 if (method.equals(METHOD_GET)) // HTTP GET // 略... doGet(req, resp); // 略 ... else if (method.equals(METHOD_HEAD)) // HTTP HEAD // 略 ... doHead(req, resp); else if (meth
12、od.equals(METHOD_POST)) // HTTP POST // 略 ... doPost(req, resp); else if (method.equals(METHOD_PUT)) // HTTP PUT // 略 ... ,protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException String protocol = req.getProtocol(); String msg = lStrings
13、.getString(http.method_get_not_supported); if (protocol.endsWith(1.1)) resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); else resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); ,,在service()的前後,這實現(xiàn)了Template Method模式。。。,現(xiàn)在好像談過了幾個模式?Worker Thread、Interceptor Filter、Template
14、Method,在service()的前後,來談一下Session怎麼建好了知道Session預設(shè)用Cookie儲存Session Id吧,餅乾我知道,在service()的前後,if (connector.getEmptySessionPath() ,public Session createSession(String sessionId) Session session = createEmptySession() session.setNew(true); session.setValid(true); session.setCreationTime(System.cur
15、rentTimeMillis()); session.setMaxInactiveInterval(this.maxInactiveInterval); if (sessionId == null) sessionId = generateSessionId(); session.setId(sessionId); sessionCounter++; return (session); ,在service()的前後,你應(yīng)該看一下org.apache.catalina. session.StandardSession,了解Session怎麼儲存好吧!接下來換個口味好了,,Servl
16、et 談好久了要來談一下 JSP 嗎? XD,從 JSP 到 Servlet,跟你下棋的其實是一隻貓.,從 JSP 到 Servlet,在我的世界中真正服務(wù)的只有Servlet沒有JSP,使用JSP不是比較簡單嗎? ,從 JSP 到 Servlet, SimpleJSP ,從 JSP 到 Servlet,package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class index_jsp extends o
17、rg.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent // 略... public void _jspInit() // 略... public void _jspDestroy() public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException
18、 // 略... ,從 JSP 到 Servlet,從 JSP 到 Servlet,public abstract class HttpJspBase extends HttpServlet implements HttpJspPage // 略... public final void init(ServletConfig config) throws ServletException super.init(config); jspInit(); _jspInit(); // 略... public final void destroy(
19、) jspDestroy(); _jspDestroy(); public final void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException _jspService(request, response); // 略... ,從 JSP 到 Servlet,在之間宣告的程式碼,都將轉(zhuǎn)譯為Servlet中的類別成員或方法 之間所包括的內(nèi)容,將被轉(zhuǎn)譯為Servlet原始碼_jspServic
20、e()方法中的內(nèi)容 運算式元素中的運算式,會直接轉(zhuǎn)譯為out物件print()輸出時的指定內(nèi)容,從 JSP 到 Servlet,隱含物件,其實就是_jspService()中的區(qū)域參考名稱,application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut();,原則上是因為都是轉(zhuǎn)成Servlet只不過角色職責不同這是另一個故事了,這麼說Servlet作的到的,JSP
21、都作的到 ,自訂標籤處理,我討厭義大利麵....<,自訂標籤處理,別傻了...我只處理 Java 的東西每個標籤後面都還是 Java 物件在處理事情。。XD,聽說使用 JSTL 就不用吃義大利麵 那是新的 HTML 標籤嗎?。。XD,自訂標籤處理,自訂標籤處理,當JSP網(wǎng)頁中包括Simple Tag自訂標籤 ,在轉(zhuǎn)譯之後... 建立自訂標籤處理器實例。 呼叫標籤處理器的setJspContext()方法設(shè)定PageContext實例。 如果是巢狀標籤中的內(nèi)層標籤,則還會呼叫標籤處理器的setParent()方法,並傳入外層標籤處理器的實例。 設(shè)定標籤處理器屬性(例如這邊是呼叫IfTag的set
22、Test()方法來設(shè)定)。 呼叫標籤處理器的setJspBody()方法設(shè)定JspFragment實例。 呼叫標籤處理器的doTag()方法。 銷毀標籤處理器實例。,cc.openhome.WhenTag _jspx_th_f_005fwhen_005f0 = new cc.openhome.WhenTag(); ... _jspx_th_f_005fwhen_005f0.setJspContext(_jspx_page_context); _jspx_th_f_005fwhen_005f0.setParent(_jspx_parent); _jspx_th_f_005fwhen_0
23、05f0.setTest(); _jspx_th_f_005fwhen_005f0.setJspBody(new Helper()); _jspx_th_f_005fwhen_005f0.doTag(); , $user.name登入成功 .. ,這代表用Simple Tag實作標籤時,你的標籤處理器不能太肥大,自訂標籤處理,當JSP中遇到TagSupport自訂標籤時 嘗試從標籤池(Tag Pool)找到可用的標籤物件,如果找到就直接使用,如果沒找到就建立新的標籤物件。 呼叫標籤處理器的setPageContext()方法設(shè)定PageContext實例。 如果是巢狀標籤中的內(nèi)層標籤,
24、則還會呼叫標籤處理器的setParent()方法,並傳入外層標籤處理器的實例。 設(shè)定標籤處理器屬性(例如這邊是呼叫IfTag的setTest()方法來設(shè)定)。 呼叫標籤處理器的doStartTag()方法,並依不同的傳回值決定是否執(zhí)行本體或呼叫doAfterBody()、doEndTag()方法(稍後詳述)。 將標籤處理器實例置入標籤池中以便再度使用。,org.apache.taglibs.standard.tag.rt.core.WhenTag _jspx_th_c_005fwhen_005f0 = (org.apache.taglibs.standard.tag.rt.core.Wh
25、enTag) _005fjspx_005ftagPool_005fc_005fwhen_0026_005ftest.get( org.apache.taglibs.standard.tag.rt.core.WhenTag.class); ... _005fjspx_005ftagPool_005fc_005fwhen_0026_005ftest.reuse( _jspx_th_c_005fwhen_005f0);,這代表用TagSupport實作標籤時,必須注意是否要重置標籤處理器的狀態(tài)。。 Pool的工作是由org.apache.jasper. runtime.TagHandle
26、rPool完成,自訂標籤處理,自訂標籤處理,public Tag get(Class handlerClass) throws JspException Tag handler = null; synchronized( this ) if (current = 0) handler = handlerscurrent--; return handler; try Tag instance = (Tag) handlerClass.newInstance(); public void reuse(Tag handler) synchronized( t
27、his ) if (current < (handlers.length - 1)) handlers++current = handler; return; ,自訂標籤處理,是啦!不過Tag File 會被我轉(zhuǎn)成 Simple Tag 的實作XD,我記得還有個 Tag File 的東西,package org.apache.jsp.tag.web; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class Errors_tag extends javax.servlet.jsp.tagext.SimpleTagSupport implements org.apache.jasper.runtime.JspSourceDependent ,最後,因為我代勞太多事了你以為有些行為很奇怪但其實看一下原始碼就什麼都知道了,我為什麼要了解這麼多細節(jié),Thanks,52,林信良 http://openhome.cc caterpillaropenhome.cc,
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 指向核心素養(yǎng)發(fā)展的高中生物學1輪復習備考建議
- 新課程新評價新高考導向下高三化學備考的新思考
- 新時代背景下化學高考備考策略及新課程標準的高中化學教學思考
- 2025屆江西省高考政治二輪復習備考建議
- 新教材新高考背景下的化學科學備考策略
- 新高考背景下的2024年高考化學二輪復習備考策略
- 2025屆高三數(shù)學二輪復習備考交流會課件
- 2025年高考化學復習研究與展望
- 2024年高考化學復習備考講座
- 2025屆高考數(shù)學二輪復習備考策略和方向
- 2024年感動中國十大人物事跡及頒獎詞
- XX教育系統(tǒng)單位述職報告教育工作概述教育成果展示面臨的挑戰(zhàn)未來規(guī)劃
- 2025《增值稅法》全文解讀學習高質(zhì)量發(fā)展的增值稅制度規(guī)范增值稅的征收和繳納
- 初中資料:400個語文優(yōu)秀作文標題
- 初中語文考試專項練習題(含答案)