前面的分析到,请求最终被封装成了一个SocketProcessor对象,放在Executors线程池中去执行。这些都还只是在tomcat内部的socket的处理层面上,那请求最终是如何被转到开发人员所写的servlet上的?
NioEndpoint.SocketProcessor所做的工作在私有方法doRun中
if (handshake ==
0) {
SocketState state = SocketState.OPEN;
// Process the request from this
socket
if (status
== null) {
state = handler.process(ka, SocketStatus.OPEN_READ);
} else {
state = handler.process(ka, status);
}
通过代码可以看出,SocketProcessor中主要做一些握手检查和资源回收的工作,在握手工作正常完成后,请求被转到handler.process进行处理。
前面在分析Connector时了解到,Connector默认使用的是org.apache.coyote.http11.Http11NioProtocol 作为ProtocolHandler。
public Http11NioProtocol() {
endpoint= new NioEndpoint();
cHandler = new Http11ConnectionHandler( this);
((NioEndpoint) endpoint).setHandler(cHandler);
setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);
setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY);
}
通过构造函数发现,在Http11NioProtocol中使用的是NioEndpoint,为这个endpoint指定的Handler是Http11ConnectionHandler类型。
Http11ConnectionHandler的类结构如下
protected static class Http11ConnectionHandler extends AbstractConnectionHandler<NioChannel,Http11NioProcessor> implements Handler
它的自己本身的process方法并不
process方法如下
@Override
public SocketState
process(SocketWrapper<NioChannel> socket,
SocketStatus status) {
if (proto.npnHandler
!= null) {
SocketState ss = proto.npnHandler.process(socket, status);
if (ss
!= SocketState.OPEN) {
return ss;
}
}
return super .process (socket,
status);
}
抛开这个很奇怪的npnHandler不管,socket的处理主要在super.process方法中完成。
AbstractConnectionHandler.process做各种状态的检查,同时做数据缓存。然后调用Processor来处理socket。这个Processor对象通过createProcessor方法创建。Http11ConnectionHandler重写了这个方法,创建的是一个Http11NioProcessor类型的对象。
Http11NioProcessor继承自AbstractHttp11Processor,在process方法处理请求 getAdapter().service(request,
response); 这样将请求传递到外面adapter上。那这个adapter是什么呢?
注意这里的getAdapter方法,请求被传回到了对应的adapter的service方法上,下面来关注这个adapter来自何处?
通过代码反馈,AbstractProcessor.setAdapter 在 AbstractHttp11Protocol.configureProcessor
中调用,传递的值,是通过AbstractHttp11Protocol.getAdapter获取
AbstractHttp11Protocol.getAdapter,也就是说,最终执行代码的adapter是来自于AbstractHttp11Protocol。还记得在Connector的startInternal函数么,在那里使用的是protocolHandler就是org.apache.coyote.http11.Http11NioProtocol,它继承了AbstractHttp11Protocol,所以这个最终的adapter是来自Http11NioProtocol的setAdapter方法传递进来。而这个方法,在Connector的initInternal中被调用,并且实际上就是这个Connector对象本身。
总结下,经过了这么一长串的处理之后,请求被转到了Connector来进行处理。