HTTP?請(qǐng)求處理
? ? ?瀏覽器訪問(wèn)服務(wù)器的過(guò)程


?http服務(wù)器并且沒(méi)有直接去調(diào)用業(yè)務(wù)類的servlet,而是交給了servlet容器。http服務(wù)器主要是監(jiān)聽(tīng)客戶端請(qǐng)求,并且將請(qǐng)求信息封裝成servletRequest,servletRespnse,傳遞給servlet容器,servlet容器接受到后,根據(jù)url和servlet的配置映射關(guān)系,找到具體處理的servlet,調(diào)用servlet.service方法處理請(qǐng)求,如果servlet還沒(méi)有被加載,則利用反射機(jī)制創(chuàng)建這個(gè)servlet,并且調(diào)用了init 初始化servlet。最后將結(jié)果封裝成servletRespnse返回給http服務(wù)器。
tomcat 實(shí)現(xiàn)了servlet規(guī)范,所以除了是一個(gè)http服務(wù)器,也具備servler容器的功能
Tomcat 整體架構(gòu)
tomcat頂層容器是server ,一個(gè)server包含多個(gè)service實(shí)例,service包含了connector和container

tomcat中2個(gè)核心組件:
1、connector

Connector用于處理連接相關(guān)的事情,并提供Socket與Request和Response相關(guān)的轉(zhuǎn)化。
那么在connector中是如何實(shí)現(xiàn)的呢?
Coyote 是 Tomcat 服務(wù)器提供的供客戶端訪問(wèn)的外部接口,客戶端通過(guò) Coyote 與服務(wù)器建立連接、發(fā)送請(qǐng)求并接受響應(yīng)。
Coyote 封裝了底層的網(wǎng)絡(luò)通信(Socket,請(qǐng)求以及響應(yīng)處理),為 Catalina 容器提供了統(tǒng)一的接口,使?Catalina 容器與具體的請(qǐng)求協(xié)議以及 IO 操作方式完全解耦。
Coyote內(nèi)部的三個(gè)組件:?Endpoint、Processor、Adapter;
Endpoint:Coyote 通信監(jiān)聽(tīng)接口,具體的 Socket 接收和發(fā)送處理器,實(shí)現(xiàn)的是TCP/IP協(xié)議,是對(duì)傳輸層的抽象。
Processor:Coyote 協(xié)議處理接口,實(shí)現(xiàn) HTTP 協(xié)議。
Adapter:由于?Request?并沒(méi)有實(shí)現(xiàn)?Servlet?規(guī)范,而?Servlet 容器只能接收?ServletRequest,因此需要引入一個(gè)適配器將?Request?轉(zhuǎn)換成?ServletRequest,再傳遞給?Servlet?容器。
通過(guò)下圖發(fā)現(xiàn) Enpoint 有多個(gè)實(shí)現(xiàn)類 Nio,Nio2,Apr,用來(lái)處理不同I/O模式。以Nio舉例

?獲取handler,然后調(diào)用process,這里process直接是抽象類??AbstractProtocol提供的方法
來(lái)看AbstractProtocol的process

?在方法里直接調(diào)用抽象類的??AbstractProcessorLight

?AbstractProcessorLight 里面調(diào)用了子類的service

?這是針對(duì)不同的協(xié)議處理不同的類。拿常用的http11舉例
獲取CoyoteAdapter,再調(diào)用service

?可以看到傳入的是coyote的request,被轉(zhuǎn)換成了connector中的request,而這個(gè)request實(shí)現(xiàn)了?HttpServletRequest接口,


往下走

map中就是拿到當(dāng)前請(qǐng)求的哪應(yīng)用下的哪個(gè)servlet,這里host,context,wrapper都進(jìn)行了封裝
2、container
看看container的架構(gòu)圖

Context和Host的區(qū)別是Context表示一個(gè)應(yīng)用,我們的Tomcat中默認(rèn)的配置下webapps下的每一個(gè)文件夾目錄都是一個(gè)Context,其中ROOT目錄中存放著主應(yīng)用,其他目錄存放著子應(yīng)用,而整個(gè)webapps就是一個(gè)Host站點(diǎn)。
我們?cè)L問(wèn)應(yīng)用Context的時(shí)候,如果是ROOT下的則直接使用域名就可以訪問(wèn),例如:www.ledouit.com,如果是Host(webapps)下的其他應(yīng)用,則可以使用http://www.ledouit.com/docs進(jìn)行訪問(wèn),當(dāng)然默認(rèn)指定的根應(yīng)用(ROOT)是可以進(jìn)行設(shè)定的,只不過(guò)Host站點(diǎn)下默認(rèn)的主營(yíng)用是ROOT目錄下的。