連接器對 Servlet 容器屏蔽了協議及 I/O 模型等的區別,無論是 HTTP 還是 AJP,在容器中獲取到的都是一個標準的 ServletRequest 對象。連接器封裝了底層的網絡通信信息,包含Socket請求及響應處理,爲容器(Catalinna)提供了統一的接口,容器從連接器拿到的是連接器封裝後的請求對象ServletRequest,使容器與具體的請求協議以及I/O操作方式完全解耦.容器處理完請求後,容器通過連接器提供的Response對象將結果下入輸出流中。
連接器的核心組件
可以看出連接器需要完成的三個高內聚功能是網絡通信,應用層協議解析,Tomcat Request/Response 與 ServletRequest/ServletResponse 的轉化。而Tomcat的設計者通過Endpoint、Processor 和 Adapter這三個組件來實現這三個功能的, 其中 Endpoint 和 Processor 放在一起抽象成了 ProtocolHandler 組件,它們的關係如下圖所示
Endpoint 負責提供字節流給 Processor,Processor 負責提供 Tomcat Request 對象給 Adapter,Adapter 負責提供 ServletRequest 對象給容器。這樣功能層次明確的實現了低耦合、高內聚的內部功能。
而至於爲什麼將Endpoint 和 Processor 放在一起抽象成ProtocolHandler 組件是因爲Tomcat的
I/O 模型和應用層協議可以自由組合,比如 NIO + HTTP 或者 NIO.2 + AJP。所以設計者們將網絡通信和應用層協議放在一起考慮,最終設計了ProtocolHandler接口來封裝這兩種變化點。各種協議和通信模型的組合有相應的具體實現類。比如:Http11NioProtocol 和AjpNioProtocol。
除了這些變化點,系統也存在一些相對穩定的部分,因此 Tomcat 設計了一系列抽象基類來封裝這些穩定的部分,抽象基類 AbstractProtocol 實現了 ProtocolHandler 接口。每一種應用層協議有自己的抽象基類,比如 AbstractAjpProtocol 和 AbstractHttp11Protocol,具體協議的實現類擴展了協議層抽象基類。
它們的繼承關係:
ProtocolHandler
連接器的ProtocolHandler是用於處理網絡連接和應用層協議的,其包含了兩個組件:Endpoint 和 Processor。
-
Endpoint
- Processor