天天看點

Tomcat源碼分析----一個http請求的經曆系列文章直達:

本章節對http請求到服務端,從監聽到處理展現給大家。

在上文中有分析Connector在啟動的時候會監聽端口。繼續以JIoEndpoint為例,在其Accptor類中:

在上面的代碼中,socket = serverSocketFactory.acceptSocket(serverSocket);與用戶端建立連接配接,将連接配接的socket交給processSocket(socket)來處理。在processSocket中,對socket進行包裝一下交給線程池來處理:

線程池處理的任務SocketProccessor,通過代碼分析:

即在SocketProcessor中,将Socket交給handler處理,這個handler就是在Http11Protocol的構造方法中指派的Http11ConnectionHandler,在該類的父類process方法中通過請求的狀态,來建立Http11Processor處理器進行相應的處理,切到Http11Proccessor的父類AbstractHttp11Proccessor中。

代碼很長,删掉的部分比較多,在這個方法裡面,可以看到Request和Response的生成,從Socket中擷取請求資料,keep-alive處理,資料包裝等等資訊,最後交給了CoyoteAdapter的service方法

在CoyoteAdapter的service方法中,主要有2個任務:

第一個是org.apache.coyote.Request和org.apache.coyote.Response到繼承自HttpServletRequest的org.apache.catalina.connector.Request和org.apache.catalina.connector.Response轉換,和Context,Wrapper定位。

第二個是将請求交給StandardEngineValve處理。

在postParseRequest方法中代碼片段:

request通過URI的資訊找到屬于自己的Context和Wrapper。而這個Mapper儲存了所有的容器資訊,不記得的同學可以回到Connector的startInternal方法中,最有一行代碼是mapperListener.start();

在MapperListener的start()方法中,

MapperListener.startInternal()方法将所有Container容器資訊儲存到了mapper中。那麼,現在初始化把所有容器都添加進去了,如果容器變化了将會怎麼樣?這就是上面所說的監聽器的作用,容器變化了,MapperListener作為監聽者。他的生成圖示:

Tomcat源碼分析----一個http請求的經曆系列文章直達:

通過Mapper找到了該請求對應的Context和Wrapper後,CoyoteAdapter将包裝好的請求交給Container處理。

從下面的代碼片段,我們很容易追蹤整個Container的調用鍊:

Tomcat源碼分析----一個http請求的經曆系列文章直達:

用時序圖畫出來則是:

Tomcat源碼分析----一個http請求的經曆系列文章直達:

最終StandardWrapperValve将請求交給Servlet處理完成

pipeline+valve處理: