国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

Tomcat處理http請求之源碼分析

瀏覽:116日期:2023-09-08 20:45:27
目錄1 請求包裝處理2 請求傳遞給Container3 Container處理請求流程1 請求包裝處理

tomcat組件Connector在啟動的時候會監(jiān)聽端口。以JIoEndpoint為例,在其Acceptor類中:

protected class Acceptor extends AbstractEndpoint.Acceptor { @Override public void run() {while (running) { …… try {//當前連接數(shù)countUpOrAwaitConnection();Socket socket = null;try { //取出隊列中的連接請求 socket = serverSocketFactory.acceptSocket(serverSocket);} catch (IOException ioe) { countDownConnection();}if (running && !paused && setSocketOptions(socket)) { //處理請求 if (!processSocket(socket)) {countDownConnection();closeSocket(socket); }} else { countDownConnection(); // Close socket right away closeSocket(socket);} } ……} }}

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

protected boolean processSocket(Socket socket) { try {SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());wrapper.setSecure(isSSLEnabled());//交給線程池處理連接getExecutor().execute(new SocketProcessor(wrapper)); } …… return true;}

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

protected class SocketProcessor implements Runnable { protected SocketWrapper<Socket> socket = null; protected SocketStatus status = null; @Override public void run() {boolean launch = false;synchronized (socket) { SocketState state = SocketState.OPEN; try {serverSocketFactory.handshake(socket.getSocket()); } …… if ((state != SocketState.CLOSED)) {//委派給Handler來處理if (status == null) { state = handler.process(socket, SocketStatus.OPEN_READ);} else { state = handler.process(socket,status);} }}} ……}

即在SocketProcessor中,將Socket交給handler處理,這個handler就是在Http11Protocol的構(gòu)造方法中賦值的Http11ConnectionHandler,在該類的父類process方法中通過請求的狀態(tài),來創(chuàng)建Http11Processor處理器進行相應(yīng)的處理,切到Http11Proccessor的父類AbstractHttp11Proccessor中。

public SocketState process(SocketWrapper socketWrapper) { RequestInfo rp = request.getRequestProcessor(); rp.setStage(org.apache.coyote.Constants.STAGE_PARSE); // Setting up the I/O setSocketWrapper(socketWrapper); getInputBuffer().init(socketWrapper, endpoint); getOutputBuffer().init(socketWrapper, endpoint); while (!getErrorState().isError() && keepAlive && !comet && !isAsync() && upgradeInbound == null && httpUpgradeHandler == null && !endpoint.isPaused()) {……if (!getErrorState().isError()) { // Setting up filters, and parse some request headers rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); try {//請求預(yù)處理prepareRequest(); } ……}……if (!getErrorState().isError()) { try {rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);//交由適配器處理adapter.service(request, response);if(keepAlive && !getErrorState().isError() && (response.getErrorException() != null ||(!isAsync() &&statusDropsConnection(response.getStatus())))) { setErrorState(ErrorState.CLOSE_CLEAN, null);}setCometTimeouts(socketWrapper); } } } ……}

可以看到Request和Response的生成,從Socket中獲取請求數(shù)據(jù),keep-alive處理,數(shù)據(jù)包裝等等信息,最后交給了CoyoteAdapter的service方法

2 請求傳遞給Container

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

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

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

public void service(org.apache.coyote.Request req,org.apache.coyote.Response res) { …… postParseSuccess = postParseRequest(req, request, res, response); …… connector.getService().getContainer().getPipeline().getFirst().invoke(request, response); ……}

在postParseRequest方法中代碼片段:

connector.getMapper().map(serverName, decodedURI, version, request.getMappingData());request.setContext((Context) request.getMappingData().context);request.setWrapper((Wrapper) request.getMappingData().wrapper);

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

public void startInternal() throws LifecycleException { setState(LifecycleState.STARTING); findDefaultHost(); Engine engine = (Engine) connector.getService().getContainer(); addListeners(engine); Container[] conHosts = engine.findChildren(); for (Container conHost : conHosts) {Host host = (Host) conHost;if (!LifecycleState.NEW.equals(host.getState())) { registerHost(host);} }}

MapperListener.startInternal()方法將所有Container容器信息保存到了mapper中。那么,現(xiàn)在初始化把所有容器都添加進去了,如果容器變化了將會怎么樣?這就是上面所說的監(jiān)聽器的作用,容器變化了,MapperListener作為監(jiān)聽者。他的生成圖示

通過Mapper找到了該請求對應(yīng)的Context和Wrapper后,CoyoteAdapter將包裝好的請求交給Container處理。

3 Container處理請求流程

從下面的代碼片段,我們很容易追蹤整個Container的調(diào)用鏈: 用時序圖畫出來則是:

最終StandardWrapperValve將請求交給Servlet處理完成。至此一次http請求處理完畢。

到此這篇關(guān)于Tomcat處理http請求之源碼分析的文章就介紹到這了,更多相關(guān)Tomcat請求處理內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Tomcat
主站蜘蛛池模板: 免费色网址| 亚洲国产老鸭窝一区二区三区 | 亚洲性欧美| 极品欧美 | 久久亚洲高清观看 | 国产精品莉莉欧美自在线线 | 波多野结衣一区二区三区在线观看 | 久久综合中文字幕一区二区三区 | 久久99精品久久久久久综合 | 欧美高清一级啪啪毛片 | www.久草| 亚洲成a人伦理 | 日本免费人成黄页网观看视频 | 欧美三级一级片 | 久久福利青草精品资源 | 成年人免费观看的视频 | 极品美女写真菠萝蜜视频 | 91成人精品视频 | 三级国产精品一区二区 | japanese日本舒服丰满 | 国产一区二区免费不卡在线播放 | 亚洲一区成人 | 可以免费看黄的网站 | 国产精品国产三级国产普通 | 亚洲性xx| 精品久久久久久久 | 欧美色性 | 怡红院在线视频观看 | 狠狠综合久久久久综合小说网 | 美女扒开腿让男生桶爽网站 | 亚洲国产一区二区a毛片日本 | 日本色综合网 | 久久99视频免费 | 亚洲日韩aⅴ在线视频 | 亚洲图片偷拍自拍 | 成人做爰视频www在线观看 | 日本一级毛片视频无遮挡免费 | a级毛片免费看 | 亚洲天堂精品在线观看 | 波多野结衣一级视频 | 成年人免费视频观看 |