连接器与容器之间通过标准的ServletRequest和ServletResponse通信。
连接器对Servlet容器屏蔽了协议及I/O模型的区别,处理Socket通信和应用层协议的解析,得到Servlet请求。
所以无论是HTTP、AJP,在容器中获取到的都是一个标准的ServletRequest对象。
连接器的详细功能:
-
监听网络端口
-
接受网络连接请求
-
读取网络请求字节流
-
根据具体应用层协议(HTTP/AJP)解析字节流,生成统一的Tomcat Request对象
-
将Tomcat Request对象转成标准的ServletRequest
-
调用Servlet容器,得到ServletResponse
-
将ServletResponse转成Tomcat Response对象
-
将Tomcat Response转成网络字节流
-
将响应字节流写回给浏览器。
提完了需求,就需要考虑它应该有哪些子模块呢?
优秀的模块化设计应该考虑高内聚、低耦合。通过分析连接器的功能,发现连接器需要完成如下高内聚的功能:
-
网络通信
-
应用层协议解析
-
Tomcat Request/Response与ServletRequest/ServletResponse的转化
因此Tomcat的设计者设计了3个组件来实现这3个功能:Endpoint、Processor和Adapter。
组件之间通过抽象接口交互。这样做还有一个好处是封装变化。这是面向对象设计的精髓,将系统中经常变化的部分和稳定的部分隔离,有助于增加复用性,并降低系统耦合度。
不管网络通信I/O模型、应用层协议、浏览器端发送的请求信息如何变化,但整体处理逻辑不变:
- Endpoint
提供字节流给Processor
- Processor
提供Tomcat Request对象给Adapter
- Adapter
提供ServletRequest对象给容器
如果要支持新的I/O方案、新的应用层协议,只需要实现相关具体子类,上层通用的处理逻辑不会变。
由于I/O模型和应用层协议可自由组合,比如NIO + HTTP或者NIO.2 + AJP。Tomcat的设计者将网络通信和应用层协议解析放在一起考虑,设计ProtocolHandler接口,封装这两种变化点。各种协议和通信模型的组合有相应的具体实现类。
比如:Http11NioProtocol和AjpNioProtocol



除了这些变化点,系统也存在一些相对稳定部分,因此Tomcat设计了一系列抽象基类来封装这些稳定部分,抽象基类AbstractProtocol实现了ProtocolHandler接口。每一种应用层协议有自己的抽象基类,比如AbstractAjpProtocol和AbstractHttp11Protocol,具体协议的实现类扩展了协议层抽象基类。

这样设计是为尽量将稳定的部分放到抽象基类,同时每一种I/O模型和协议的组合都有相应的具体实现类,我们在使用时可以自由选择。
连接器模块的核心组件:
-
Endpoint
-
Processor
-
Adapter
Endpoint和Processor放在一起抽象成了ProtocolHandler组件

===================================================================
连接器用ProtocolHandler处理网络连接、应用层协议,包含如下重要部件
Endpoint
通信端点,即通信监听的接口,是具体的Socket接收和发送处理器,是对传输层的抽象,因此Endpoint用来实现TCP/IP协议。
Endpoint是一个接口,对应的抽象实现类是AbstractEndpoint,而AbstractEndpoint的具体子类,比如在NioEndpoint和Nio2Endpoint中,有两个重要的子组件:Acceptor和SocketProcessor。
Acceptor
用于监听Socket连接请求。SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在run方法里调用协议处理组件Processor进行处理。
为了提高处理能力,SocketProcessor被提交到线程池来执行。而这个线程池叫作执行器(Executor)。
Processor
Processor用来实现应用层的HTTP协议,接收来自Endpoint的Socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理。
Processor是一个接口,定义了请求的处理等方法。它的抽象实现类AbstractProcessor对一些协议共有的属性进行封装,没有对方法进行实现。具体的实现有AjpProcessor、Http11Processor等,这些具体实现类实现了特定协议的解析方法和请求处理方式。
连接器的组件图:

Endpoint接收到Socket连接后,生成一个SocketProcessor任务提交到线程池处理,SocketProcessor的run方法会调用Processor组件去解析应用层协议,Processor通过解析生成Request对象后,会调用Adapter的Service方法。
一个连接器对应一个监听端口,比如一扇门,一个web应用是一个业务部门,进了这个门后你可以到各个业务部门去办事。
Tomcat配置的并发数是endpoint里那个线程池。
由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来“存放”这些请求信息。
ProtocolHandler接口负责解析请求并生成Tomcat Request类,但这个Request对象不是标准ServletRequest,不能用Tomcat Request作为参数调用容器。
于是Tomcat引入CoyoteAdapter,连接器调用CoyoteAdapter的sevice方法,传入Tomcat Request对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容器的service方法。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。


既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
结语
小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。
我们选择的这个行业就一直要持续的学习,又很吃青春饭。
虽然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。
送给每一位想学习Java小伙伴,用来提升自己。

本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
能被裁。
送给每一位想学习Java小伙伴,用来提升自己。
[外链图片转存中…(img-hfsVaSmM-1712729311162)]
本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
本文详细解释了连接器在Servlet容器中的作用,如何通过标准接口处理网络请求,介绍了Endpoint、Processor和Adapter等关键组件的职责与设计原则,以及它们如何适应不同的I/O模型和协议变化。作者强调了模块化设计的重要性,以及Tomcat如何通过抽象和继承实现灵活性和复用性。
927

被折叠的 条评论
为什么被折叠?



