先看下coyote框架的类结构图:
tomcat可以配置连接器,即http连接器或ajp连接器,该配置在tomcat启动后会实例化为一个Connector对象,该对象包含了用户可以设定的一些参数,如端口,协议,bio/nio,http/https,证书等等,然后根据这些参数实例化出具体的协议处理器,如 http/8080/bio对应Http11Protocol,而nio则对应Http11NioProtocol,若是ajp协议则实例化出AjpProtocol/AjpAprProtocol,若使用到本地接口apr,则使用apr相关的协议处理器,这些协议处理器对外都是以 ProtocolHandler 接口开放,每个协议处理器都有对应的业务处理器,即Processor,该抽象的职责是将协议栈中的数据流对应转换为coyote的内部表示,即coyote的request和response对象,不同协议构造coyote的request和response对象的方式不同,所以协议处理器和Processor是一一对应的,从源码上看每个Processor都是由具体的协议处理器创建出来的(这里使用到了模板方法,创建的接口位于AbstractProtocol内部,主流程调用此接口会代理到具体的实现类上),这样AbstractHttp11Processor和AbstractAjpProcessor就不难理解,他们是http和ajp协议处理器对应的Processor的抽象,这里会发现一个UpgradeProcessor,这是个特殊的Processor,他的作用是处理 http 协议升级的,如http协议升级到 websocket协议时就会用到此协议(PS:http协议升级在其他文章中介绍,这里不写了)。
来看下 AbstractEndpoint,这个抽象类终端连接的抽象,里面定义了很多连接公共的操作方式,对于泛华的 BIO/NIO/APR方式的特殊处理,则由其子类JIoEndpoint/NioEndpoint/AprEndpoint来完成,AbstractEndpoint的职责是在tomcat连接器(coyote)框架的最前端接收用户的tcp/http请求(如sock的监听/读/写)进而交给具体的协议处理。
好了,梳理下tomcat coyote 整体架构,Connector的职责是建立coyote整体架构,它初始化并控制coyote架构的整体状态,coyote的整体架构如下:
AbstractEndpoint开启socket监听和读写,其工作在最底层,将接收到的socket交给绑定在此端口上面的协议处理器ProtocolHandler来处理,ProtocolHandler对协议作基础处理(包括连接管理、丢弃、复用、安全等),最终交给业务处理器Processor来生成coyote的request和response,至此coyote的工作就完成了,那么coyote处理后的数据如果进行后续处理呢?coyote框架定义了处理接口Adapter,应用层框架(如 web容器)通过向coyote注册一个 Adapter 对象来实现coyote到应用层框架的整合,coyote处理完成后会调用注册进来的Adapter实例的 service(Request req, Response res) ,从而应用从框架便可以获取到coyote的request和response,进而进行后续业务,典型的就是web容器,web容器在接收到coyote的request和response后会转换成为servlet规范中的request和response,并最终进入到应用的filter和servlet。