1.Tomcat Connector接收请求
线程池中线程TaskThread#run进行处理(http-nio线程):
- SocketProcessorBase#run(是个Runnable任务)
- NioEndpoint.SocketProcessor#doRun
- AbstractProtocol.ConnectionHandler#process
- AbstractProcessorLight#process
- Http11Processor#service
- CoyoteAdapter#service
Acceptor
Acceptor#run()
- LimitLatch限制客户端连接总数,默认是8*1024
- socket = endpoint.accept()
- 创建NioChannel,并设置为非阻塞,然后poller.register(socketWrapper);
AbstractEndpoint#startAcceptorThread
- Acceptor线程只有一个
Poller
NioEndpoint.Poller#register
- socketWrapper关注SelectionKey.OP_READ
- 新建PollerEvent(OP_REGISTER),放到events队列中(SynchronizedQueue)
NioEndpoint.Poller#run
- events(),这里从队列events取出事件,如果是注册,则向selector注册OP_READ事件
- 然后调用selector.select(selectorTimeout)
- 如果有读写事件,则遍历SelectionKey进行处理processKey(sk, socketWrapper)
- 创建SocketProcessor,事件类型是SocketEvent.OPEN_READ,获取线程池,丢到线程池执行executor.execute(sc);
NioEndpoint#startInternal
- poller = new Poller();该线程也只有一
Executor执行线程池
NioEndpoint#startInternal
- AbstractEndpoint#createExecutor
- 线程池数量默认最小是10,最大是200
public void createExecutor() {
internalExecutor = true;
TaskQueue taskqueue = new TaskQueue();
TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());
executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
taskqueue.setParent( (ThreadPoolExecutor) executor);
}
SocketProcessor
NioEndpoint.SocketProcessor#doRun
- getHandler().process(socketWrapper, event)
- 这里的handler是在AbstractHttp11Protocol构造方法里面创建的ConnectionHandler
- processor.process(wrapper, status);这里processor是Http11Processor
Http11Processor
Http11Processor#process
- AbstractProcessorLight#process
- Http11Processor#service
- 最终CoyoteAdapter#service
2.Tomcat 多级容器处理
Request中MappingData
CoyoteAdapter#service
- CoyoteAdapter#postParseRequest(处理完这个,然后才调用容器的pipeline)
- Mapper#map()
- Mapper#internalMap,此时入参
host:localhost
uri:/order-service/order/add
核心就在Mapper#internalMap,在此进行匹配:
- 1)MappedHost mappedHost = exactFindIgnoreCase(hosts, host);在Mapper.hosts里面匹配host(localhost)
- 2)find(contexts, uri);在匹配的mappedHost.contextList.contexts中匹配uri(/order-service/order/add)
- 3)internalMapWrapper(contextVersion, uri, mappingData);匹配Wrapper
A)Rule 1 -- Exact Match
B)Rule 2 -- Prefix Match
C)Rule 3 -- Extension Match
D)Rule 4 -- Welcome resources processing for servlets
E)Rule 7 -- Default servlet
容器pipeline调用
CoyoteAdapter#service
- StandardEngineValve#invoke
- StandardHostValve#invoke
- StandardContextValve#invoke
- StandardWrapperValve#invoke
- ApplicationFilterChain#doFilter
3.过滤器处理
ApplicationFilterChain#doFilter
- OncePerRequestFilter#doFilter
- CharacterEncodingFilter#doFilterInternal
- FormContentFilter#doFilterInternal
- RequestContextFilter#doFilterInternal
- WsFilter#doFilter
4.Servlet处理(SpringMVC的DispatcherServlet的处理)
过滤器结束后:
- ApplicationFilterChain#internalDoFilter
- HttpServlet#service(),这里实际是DispatcherServlet
- DispatcherServlet#doDispatch
SpringMVC和Tomcat的结合点是Servlet。
Springmvc的核心是一个DispatcherServlet,负责请求的解析,拦截,转发,响应等等。
DispatchServlet实现了HttpServlet,那么SpringMVC在Tomcat看来,其实就是一个Servlet。所有的http请求都是映射到这个DispatchServlet上,请求进入到DispatchServlet中之后,就算进入到了框架之中了,由这个Servlet来统一的分配http请求到各个Controller。
5.整体流程总结
整体流程:
- 1)Acceptor接收客户端连接请求
- 2)Poller接收客户端读写请求
- 3)Executor执行SocketProcessor任务
- 4)Http11Processor处理Http请求
- 5)CoyoteAdapter首先进行host/context/wrapper匹配,放到Request的MappingData中
- 6)各级容器Pipeline的阀门处理
- 7)ApplicationFilterChain过滤器链处理
- 8)DispatcherServlet进行处理(如下为SpringMVC处理流程)
- 9)会从三个HandlerMapping(this.handlerMappings)根据request查找Handler,并找出对应拦截器组成HandlerExecutionChain
- 10)拿到对应的Handler后,会转换为HandlerAdapter
- 11)mappedHandler#applyPreHandle 拦截器前置方法
- 12)HandlerAdapter#handle
A)参数解析RequestParamMethodArgumentResolver#resolveName
B)参数类型转换:String -> User,可以定义类型转换器PropertyEditorSupport,然后@InitBinder,注册User -> PropertyEditorSupport)
C)doInvoke(args)调用我们定义的目标方法
D)messageConverter进行类型转换
E)返回值解析器处理返回值 - 13)mappedHandler.applyPostHandle 拦截器后置方法
- 14)processDispatchResult()渲染视图,执行拦截器afterCompletion方法
网友评论