3-tomcat-接收web请求到进入Spring框架前

330 阅读1分钟

不可能通过一篇文章就学会源码。

tomcat使用了nio(nio基于channel和buffer,并且通过slector实现多路复用)。

一、初始化阶段

1)创建SocketServer并绑定到nio的channel中

2)Selector.open() 创建一个selector

3)将创建的selector放入一个线程中,这个线程不断循环扫描绑定的channel,如果channel中有数据,则读取数据进行处理

  1. 在NioEndPoint.Acceptor线程中,循环监听TCP的连接请求

                                                  图1 初始化ServerSocketChannel

                                                        图2 创建Selector

                                   图3 把创建的Selector传入BlockPoller线程对象

                                图4 NioEndPoint.Acceptor监听TCP连接请求

二、接收请求阶段

1)如图4中,在接收到连接请求后,会开始进行处理

2)最终,将socket封装成PollerEvent,放入到events队列中

  1. 在 NioEndPoint.Poller线程中,循环读取events队列,执行元素中run()方法,将socket的读事件注册到selector上

 3.1)如果selector读取到数据时,则启动一个线程开始处理

                                  图5 将socket连接封装后放入events队列

                                                  图6 元素中的run()方法

                                       图7 selector读取到数据,开始处理

                                              图8 启动一个线程处理请求

三、线程处理请求阶段

继续上一节,现在看线程内部的处理流程。

处理请求的类是NioEndpoint.SocketProcessor

图9 NioEndpoint.SocketProcessor

                                   图10 AbstractProtocol.ConnectionHandler

开始走入处理流(责任链模式)

                                                      图11 开始走入处理流

待验证问题:

1. request 如何匹配到context

2. tomcat责任链过滤器

已经找到可以处理请求的Context,并执行web应用自定义的过滤器

                                                        图12 自定义的过滤器

最后,进入到 org.springframework.web.servlet.DispatcherServlet

                                                    图13 DispatcherServlet