本章節對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作為監聽者。他的生成圖示:
通過Mapper找到了該請求對應的Context和Wrapper後,CoyoteAdapter将包裝好的請求交給Container處理。
從下面的代碼片段,我們很容易追蹤整個Container的調用鍊:
用時序圖畫出來則是:
最終StandardWrapperValve将請求交給Servlet處理完成
pipeline+valve處理: