1Processor, 它用来解析 Socket,将 Socket 中的内容封装到 Request 中。注意这个 Request 是临时使用的一个类,它的全类名是 org.apache.coyote.Request ,
postParseRequest() 方法封装一下 Request,并处理一下映射关系(从 URL 映射到相应的 Host 、Context 、Wrapper )。
CoyoteAdapter 将 Rquest 提交给 Container 处理之前,并将 org.apache.coyote.Request 封装到 org.apache.catalina.connector.Request ,传递给 Container 处理的 Request 是 org.apache.catalina.connector.Request 。
connector.getService().getMapper().map() ,用来在 Mapper 中查询 URL 的映射关系。映射关系会保留到 org.apache.catalina.connector.Request 中,Container 处理阶段 request.getHost() 是使用的就是这个阶段查询到的映射主机,以此类推 request.getContext() 、request.getWrapper() 都是。
connector.getService().getContainer().getPipeline().getFirst().invoke() 会将请求传递到 Container 处理,当然了 Container 处理也是在 Worker 线程中执行的,但是这是一个相对独立的模块,所以单独分出来一节。
Container
- 需要注意的是,基本上每一个容器的
StandardPipeline 上都会有多个已注册的 Valve ,我们只关注每个容器的 Basic Valve。其他 Valve 都是在 Basic Valve 前执行。
request.getHost().getPipeline().getFirst().invoke() 先获取对应的 StandardHost ,并执行其 pipeline。
request.getContext().getPipeline().getFirst().invoke() 先获取对应的 StandardContext ,并执行其 pipeline。
request.getWrapper().getPipeline().getFirst().invoke() 先获取对应的 StandardWrapper ,并执行其 pipeline。
- 最值得说的就是
StandardWrapper 的 Basic Valve,StandardWrapperValve
allocate() 用来加载并初始化 Servlet ,值的一提的是 Servlet 并不都是单例的,当 Servlet 实现了 SingleThreadModel 接口后,StandardWrapper 会维护一组 Servlet 实例,这是享元模式。当然了 SingleThreadModel 在 Servlet 2.4 以后就弃用了。
createFilterChain() 方法会从 StandardContext 中获取到所有的过滤器,然后将匹配 Request URL 的所有过滤器挑选出来添加到 filterChain 中。
doFilter() 执行过滤链,当所有的过滤器都执行完毕后调用 Servlet 的 service() 方法。
Reference
- 《How Tomcat works》
- 《Tomcat 架构解析》– 刘光瑞
- Tomcat-9.0-doc
- apache-tomcat-9.0.0.M22-src
- tomcat架构分析 (connector NIO 实现)
|