-
概述
连接器是TOMCAT处理请求的入口,所有请求都是由 连接器 来接收并发起整个请求处理过程。连接器一般与TOMCAT的Service关联。一个Service持有一个或多个连接器。
-
创建连接器
TOMCAT启动时会在load阶段根据 server.xml 中的配置创建对应的Connector,相关的配置代码如下:
<Service name="Catalina">
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443" />
<!--省略其他内容-->
</Service>
我们来看一下TOMCAT是如何根据配置文件来选择对应连接器的。
/**
* Coyote Protocol handler class name.
* Defaults to the Coyote HTTP/1.1 protocolHandler.
*/
//默认的连接器
protected String protocolHandlerClassName =
"org.apache.coyote.http11.Http11Protocol";
//这里只贴出我们关注的代码
public Connector(String protocol) throws Exception {
//方法的实现在下面
setProtocol(protocol);
// Instantiate protocol handler
//反射实例化类
try {
Class clazz = Class.forName(protocolHandlerClassName);
this.protocolHandler = (ProtocolHandler) clazz.newInstance();
} catch (Exception e) {
log.error(sm.getString
("coyoteConnector.protocolHandlerInstantiationFailed", e));
}
}
public void setProtocol(String protocol) {
//...省略一些代码
if ("HTTP/1.1".equals(protocol)) {
setProtocolHandlerClassName
("org.apache.coyote.http11.Http11Protocol");
} else if ("AJP/1.3".equals(protocol)) {
setProtocolHandlerClassName
("org.apache.jk.server.JkCoyoteHandler");
} else if (protocol != null) {
setProtocolHandlerClassName(protocol);
}
//如果传入的protocol为null,则使用默认的连接器
//...省略一些代码
}
从代码中可以看到,TOMCAT在创建Connection 的时候就会根据protocol属性的值选择对应的 protocolHandler 实现类(Connection只是一个容器,真正做处理的是Connection内持有的 protocolHandler )。如果protocol的值在TOMCAT中没有定义,会直接将这个值作为全路径类名来使用。所以将配置稍作修改如下:
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11Protocol"
connectionTimeout="20000"
redirectPort="8443" />
同样可以启动并处理HTTP请求。
在初始化Connector之后,TOMCAT会将配置文件中Connector标签的其他属性,全都赋予当前的Connector实例。
Http11Protocol 是HTTP连接器的实现,负责处理HTTP请求,是TOMCAT的默认连接器,也是最常用的连接器。
下面我们就以Http11Protocol为例来看看连接器的初始化和调用过程。
- 连接器的初始化与启动
连接器的初始化与启动过程如图所示。
1,2,3是连接器的初始化过程。4,5,6,7,8是启动过程。
- Connector调用Http11Protocol的init方法
- Http11Protocol调用JIoEndpoint的init方法
- JIoEndpoint调用ServerSocketFactory的createSocket方法创建一个默认的serverSocket,到这里TOMCAT对网络的监听就已经初始化完成了。
- Connector调用Http11Protocol的start方法
- Http11Protocol调用JIoEndpoint的start方法
- JIoEndpoint初始化一个Acceptor实例
- JIoEndpoint将Acceptor作为单独的线程启动
- Acceptor启动之后,循环调用ServerSocketFactory的acceptSocket方法,接收并处理网络请求