程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> How Tomcat works — 六、tomcat處理請求,tomcatworks

How Tomcat works — 六、tomcat處理請求,tomcatworks

編輯:JAVA綜合教程

How Tomcat works — 六、tomcat處理請求,tomcatworks


tomcat已經啟動完成了,那麼是怎麼處理請求的呢?怎麼到了我們所寫的servlet的呢?

目錄

  • Http11ConnectionHandler
  • Http11Processor
  • CoyoteAdapter
  • StandardEngineValve
  • StandardWrapperValve
  • 總結

Http11ConnectionHandler

在tomcat 啟動之後會使用socket.accept接收請求,接收到之後會調用自己的processSocket來處理請求,在該方法中啟動一個SocketProcessor線程,在該內部類的潤方法內調用Http11ConnectionHandler.process,過程如下:

實際執行的是超類AbstractConnectionHandler.process方法,主要作用:

  • 從connections裡面獲取processor
  • 如果processor為null則嘗試從隊列裡面獲取一個processor,該隊列是一個RecycledProcessors類繼承自ConcurrentLinkedQueue,是一個線程安全的隊列,因為同時會有多個線程獲取processor
  • 如果processor還是為null(表明還未創建或者已經用完),那麼創建一個新的processor,調用Http11ConnectionHandler.createProcessor,該方法會創建一個新的Http11Processor(但是並不會立即添加到上面提到的隊列裡面,而是在請求處理完成之後才會添加到隊列裡面)
  • 調用Http11Processor.process

Http11Processor

在connector出來完成之後會啟動processor線程,關於processor的類圖如下:

和處理協議一 一對應,不同的協議也有不同的processor,在AbstractProcessor裡面有Request和Response,不過是org.apache.coyote包下面的,這是在connector層面的連接器,是primitive的。

實際執行的也是超類AbstractHttp11Processor.process,主要功能如下:

  • 獲得socket的輸入、輸出流
  • parsing request header、method、requestURI
  • 設置request filters,並設置content-length等header
  • 調用CoyoteAdapter.service

CoyoteAdapter

由connector和processor過渡到container的類,使用了adapter模式,將container適配到processor。主要的方法就是CoyoteAdapter.service:

  • 獲取org.apache.connector.Request和Response,這兩個類經過facade模式之後就是最後我們servlet中使用的request和response
  • 如果是新建的processor,request和response為null,那麼就調用connector.createRequest和createResponse新建,然後設置到coyote.request的note中
  • 調用postParseRequest,添加wrapper和servlet之間的映射(在後面load servlet的時候用到),parseSessionId解析sessionId
  • connector.getService().getContainer().getPipeline().getFirst().invoke(request, response),依次是:Connector,StandardService,StandardEngine,StandardPipeline,StandardEngineValve
  • 在執行完之後,完成請求也在這個方法中:request.finishRequest(上面說過的processor就是在這兒回收的),response.finishResponse(請求在這裡返回到客戶端,outputStream)
  • 最後,recycle request和response,清空request和response所有信息

StandardEngineValve

這個是StandardEngine的基礎閥(每個容器都有一個pipeline,每個pipeline都有一個基礎閥,用來調用servlet)在adapter中最後調用到了StandardEngineValve.invoke方法,該方法主要進行了以下操作

  • request.getHost:獲取host
  • host.getPipeline().getFirst().invoke(request, response):依次是StandardHost,StandardPipeline,StandardHostValve

接下來就是容器逐級依次調用,下一個是StandardHostValve:

context.getPipeline().getFirst().invoke(request, response);

在接下來是NonloginAuthencator

context.invokeNext(request,response)

接著是StandardContextValve

 wrapper.getPipeline().getFirst().invoke(request, response);

接下來就是StandardWrapperValve,在這裡進行了很多工作。

StandardWrapperValve

這是StandardWrapper的基礎閥,作用就是獲取servlet實例並調用filterChain,主要方法是invoke:

  • 獲取容器wrapper,通過wrapper分配一個servlet實例
  • 使用ApplicationFilterFactory創建filterChain
  • filterChain.doFilter調用filter鏈,這裡沒有配置額外的filter,只有一個默認的WsFilter(對websocket的支持),在所有的filterChain調用完成之後,就是調用servlet.service 方法,開始進入我們寫的servlet裡面
  • 在上面調用完成之後,釋放filterChain(將filter置空),釋放servlet(會受到instantPool裡面)

 

這個執行流程如上,最後一個UserServlet是我自定義的簡單的servlet。到了自定義的servlet之後,依次請求也就是到了最深層,接下來就是逐層范返回,並做一些清理工作(當然了還有一些長連接的維護等等)。

總結

從socket監聽接收開始,到我們自定義的servlet處理請求結束,是一次完整的請求過程,為了說明白請求的整個過程,省略了很多細節,比如:三種request(coyote.Request,connector.Request,RequestFacade)之間的轉換,session的管理等等。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved