tomcat源码:Connector模块

前言

Connector是Tomcat的连接器,其主要任务是负责处理浏览器发送过来的请求,并创建一个Request和Response的对象用于和浏览器交换数据,然后产生一个线程用于处理请求,Connector会把Request和Response对象传递给该线程,该线程的具体的处理过程是Container容器的事了。执行过程分为以下几个步骤 

  1. 实例化Connector,构造一个Connector对象
  2. 调用Connector的initIntenal方法,初始化Connetor
  3. 调用ProtocolHanlder的init方法,完成ProtocolHanlder的初始化。这个过程包括了创建线程池并创建一个线程处理浏览器请求
  4. 调用Connector的startIntenal方法,启动Connector
  5. 调用ProtocolHandler的start方法,启动Protocolhanlder
  6. 调用MapperListener的start方法,启动监听器程序

为了对Connector的执行过程有一个大概的印象,可以参考下面的序列图:

Connector启动过程

注意:由于Tomcat还支持AJP协议,但为了简化,我画的这个序列图是基于Http协议的,这也是我们在Web开发中接触最多的协议了。

在深入Connector之前我们先看看Connector类的结构:

Connector属性 
Connector部分方法

既然是处理浏览器请求,那么需要支持http协议,在Tomcat中有两种协议处理器:HTTP/1.1与AJP/1.3协议处理器。在server.xml中已经指明tomcat所支持的两种协议:

代码清单3-1:

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">Connector</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">port</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8080"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">protocol</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"HTTP/1.1"</span>
               <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">connectionTimeout</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"20000"</span>
               <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">redirectPort</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8443"</span> /></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">Connector</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">port</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8009"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">protocol</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"AJP/1.3"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">redirectPort</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8443"</span> /></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

在tomcat中是怎么样分别处理这两种协议的呢,我们可以ProtocolHanlder类中找到答案:

ProtocolHanlder协议处理器

图中被选中的就是Tomcat默认使用协议处理器,其实现过程与Java标准Socket编程是一样的,在tomcat中可以使用Connetor类的setProtocol方法,看看源码就知道了:

代码清单3-2:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> setProtocol(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> protocol) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (AprLifecycleListener<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>isAprAvailable()) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"HTTP/1.1"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) {
                setProtocolHandlerClassName
                    (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.http11.Http11AprProtocol"</span>);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AJP/1.3"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) {
                setProtocolHandlerClassName
                    (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.ajp.AjpAprProtocol"</span>);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (protocol <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) {
                setProtocolHandlerClassName(protocol);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                setProtocolHandlerClassName
                    (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.http11.Http11AprProtocol"</span>);
            }
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"HTTP/1.1"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) {
                setProtocolHandlerClassName
                    (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.http11.Http11Protocol"</span>);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AJP/1.3"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) {
                setProtocolHandlerClassName
                    (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.ajp.AjpProtocol"</span>);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (protocol <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) {
                setProtocolHandlerClassName(protocol);
            }
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>

从第2个if子句的最后一个else可以知道tomcat默认使用的是http1.1协议。 
我们再看看Connector的初始化过程:

代码清单3-3:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">initInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> LifecycleException {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.initInternal();
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Initialize adapter</span>
        adapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> CoyoteAdapter(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);
        protocolHandler.setAdapter(adapter);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Make sure parseBodyMethodsSet has a default</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == parseBodyMethodsSet ) {
            setParseBodyMethods(getParseBodyMethods());
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (protocolHandler.isAprRequired() &&
                !AprLifecycleListener.isAprAvailable()) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException(
                    sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.protocolHandlerNoApr"</span>,
                            getProtocolHandlerClassName()));
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            protocolHandler.init();
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException
                (sm.getString
                 (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.protocolHandlerInitializationFailed"</span>), e);
        }
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Initialize mapper listener</span>
        mapperListener.init();
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>

从这段代码中可以看到:首先调用父类org.apache.catalina.util.LifecycleMBeanBase的初始化方法,然后创建一个Adapter,然后设置protocolHanlder(协议处理器)的Adapter,同时判断传过来的请求的请求方法(比如get或者post),如果没有指明请求方法,默认使用post处理,然后调用protocolHanlder的初始化方法,最后调用mapperListener的初始化方法,而mapperListener的初始化方法调用的是org.apache.catalina.util.LifecycleBase的init方法,我们重点关注protocolHanlder的初始化方法,具体是实现在AbstractProtocol抽象类中,其直接子类有AbstractAjpProtocol和AbstractHttp11Protocol,分别对应的是两种不同的处理协议,所以协议处理器的初始化方法是在其子抽象类(实现ProtocolHanlder接口的抽象类)来实现的,这里看看AbstractHttp11Protocol的初始化方法:

代码清单3-4:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isInfoEnabled())
            getLog().info(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.init"</span>,
                    getName()));
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (oname == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Component not pre-registered so register it</span>
            oname = createObjectName();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (oname != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                Registry.getRegistry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>).registerComponent(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, oname,
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.domain != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                tpOname = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ObjectName(domain + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">":"</span> +
                        <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"type=ThreadPool,name="</span> + getName());
                Registry.getRegistry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>).registerComponent(endpoint,
                        tpOname, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {
                getLog().error(sm.getString(
                        <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.mbeanRegistrationFailed"</span>,
                        tpOname, getName()), e);
            }
            rgOname=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ObjectName(domain +
                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">":type=GlobalRequestProcessor,name="</span> + getName());
            Registry.getRegistry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>).registerComponent(
                    getHandler().getGlobal(), rgOname, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> );
        }
        String endpointName = getName();
        endpoint.setName(endpointName.substring(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, endpointName.length()-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>));
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            endpoint.init();
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception ex) {
            getLog().error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.initError"</span>,
                    getName()), ex);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> ex;
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li></ul>

打断点调试可以知道oname的值是Tomcat:type=ProtocolHandler,port=auto-1,address="127.0.0.1",tpOname是Tomcat:type=ProtocolHandler,port=auto-1,address="127.0.0.1",rOname是Tomcat:type=GlobalRequestProcessor,name="http-bio-127.0.0.1-auto-1",我们重点关注endpoint的init方法,主要完成以下几个过程:

  1. 设置线程接收数和最大连接数
  2. 创建线程池,启动监听的线程监听用户请求
  3. 启动一个线程处理请求

初始化完成Connector就可以启动了,启动阶段调用startInternal方法:

代码清单3-5:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> LifecycleException {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Validate settings before starting</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getPort() < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException(sm.getString(
                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.invalidPort"</span>, Integer.valueOf(getPort())));
        }
        setState(LifecycleState.STARTING);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            protocolHandler.start();
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {
            String errPrefix = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.service != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                errPrefix += <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"service.getName(): \""</span> + <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.service.getName() + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\"; "</span>;
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException
                (errPrefix + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" "</span> + sm.getString
                 (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.protocolHandlerStartFailed"</span>), e);
        }
        mapperListener.start();
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

可以看出Connector调用protocolHandler.start()方法,继续看看这个方法的源码:

代码清单3-6:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">start</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isInfoEnabled())
            getLog().info(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.start"</span>,
                    getName()));
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            endpoint.start();
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception ex) {
            getLog().error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.startError"</span>,
                    getName()), ex);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> ex;
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

这个方法又调用了endpoint.start()方法:

代码清单3-7:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">start</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (bindState == BindState.UNBOUND) {
            bind();
            bindState = BindState.BOUND_ON_START;
        }
        startInternal();
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

然后又调用了org.apache.tomcat.util.net.AbstractEndpoint.startInternal()方法:

代码清单3-8:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!running) {
            running = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
            paused = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Create worker collection</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getExecutor() == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                createExecutor();
            }
            initializeConnectionLatch();
            startAcceptorThreads();
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Start async timeout thread</span>
            Thread timeoutThread = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Thread(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AsyncTimeout(),
                    getName() + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"-AsyncTimeout"</span>);
            timeoutThread.setPriority(threadPriority);
            timeoutThread.setDaemon(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
            timeoutThread.start();
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>
  1. 设置线程接收数和最大连接数
  2. 创建线程池,启动监听的线程监听用户请求
  3. 启动一个线程处理异步请求

这里启动了一个异步线程处理请求,这个异步线程是如何执行的呢?

代码清单3-9:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * Async timeout thread
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AsyncTimeout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Runnable</span> {</span>
        <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
         * The background thread that checks async requests and fires the
         * timeout if there has been no activity.
         */</span>
        <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() {
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Loop until we receive a shutdown command</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (running) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                    Thread.sleep(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>);
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InterruptedException e) {
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Ignore</span>
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> now = System.currentTimeMillis();
                Iterator<SocketWrapper<Socket>> sockets =
                    waitingRequests.iterator();
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (sockets.hasNext()) {
                    SocketWrapper<Socket> socket = sockets.next();
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> access = socket.getLastAccess();
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (socket.getTimeout() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> &&
                            (now-access)>socket.getTimeout()) {
                        processSocketAsync(socket,SocketStatus.TIMEOUT);
                    }
                }
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Loop if endpoint is paused</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (paused && running) {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                        Thread.sleep(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>);
                    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InterruptedException e) {
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Ignore</span>
                    }
                }
            }
        }
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//processSocket</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">processSocketAsync</span>(SocketWrapper<Socket> socket,
            SocketStatus status) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> (socket) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (waitingRequests.remove(socket)) {
                    SocketProcessor proc = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SocketProcessor(socket,status);
                    ClassLoader loader = Thread.currentThread().getContextClassLoader();
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//threads should not be created by the webapp classloader</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (Constants.IS_SECURITY_ENABLED) {
                            PrivilegedAction<Void> pa = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> PrivilegedSetTccl(
                                    getClass().getClassLoader());
                            AccessController.doPrivileged(pa);
                        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                            Thread.currentThread().setContextClassLoader(
                                    getClass().getClassLoader());
                        }
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// During shutdown, executor may be null - avoid NPE</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!running) {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                        }
                        getExecutor().execute(proc);
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//TODO gotta catch RejectedExecutionException and properly handle it</span>
                    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (Constants.IS_SECURITY_ENABLED) {
                            PrivilegedAction<Void> pa = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> PrivilegedSetTccl(loader);
                            AccessController.doPrivileged(pa);
                        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                            Thread.currentThread().setContextClassLoader(loader);
                        }
                    }
                }
            }
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// This means we got an OOM or similar creating a thread, or that</span>
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// the pool and its queue are full</span>
            log.error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"endpoint.process.fail"</span>), t);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li></ul>

org.apache.tomcat.util.net.JIoEndpoint.SocketProcessor的职责是把具体的请求处理过程委派给org.apache.tomcat.util.net.JIoEndpoint.Handler,然后根据handler返回的不同SocketState,来决定是否关闭连接或者进行下一轮处理。

代码清单3-10:

<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">public void run() {
            boolean launch = false;
            synchronized (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>) {
                try {
                    SocketState <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = SocketState.OPEN;
                    try {
                        <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> SSL handshake
                        serverSocketFactory.handshake(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.getSocket());
                    } catch (Throwable t) {
                        ExceptionUtils.handleThrowable(t);
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.isDebugEnabled()) {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.debug(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"endpoint.err.handshake"</span>), t);
                        }
                        // Tell to <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">close</span> the <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = SocketState.CLOSED;
                    }
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> != SocketState.CLOSED)) {
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (status == null) {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = handler.process(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>, SocketStatus.OPEN_READ);
                        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = handler.process(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>,status);
                        }
                    }
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.CLOSED) {
                        <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> Close <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.isTraceEnabled()) {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.trace(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Closing socket:"</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>);
                        }
                        countDownConnection();
                        try {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.getSocket().<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">close</span>();
                        } catch (IOException e) {
                            <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> Ignore
                        }
                    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.OPEN ||
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.UPGRADING ||
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.UPGRADING_TOMCAT  ||
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.UPGRADED){
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.setKeptAlive(true);
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.access();
                        launch = true;
                    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.LONG) {
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.access();
                        waitingRequests.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>);
                    }
                } finally {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (launch) {
                        try {
                            getExecutor().execute(new SocketProcessor(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>, SocketStatus.OPEN_READ));
                        } catch (RejectedExecutionException <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">x</span>) {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">warn</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Socket reprocessing request was rejected for:"</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">x</span>);
                            try {
                                <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//unable</span> to handle connection at this <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">time</span>
                                handler.process(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>, SocketStatus.DISCONNECT);
                            } finally {
                                countDownConnection();
                            }
                        } catch (NullPointerException npe) {
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (running) {
                                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"endpoint.launch.fail"</span>),
                                        npe);
                            }
                        }
                    }
                }
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span> = null;
            <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> Finish up this request
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li></ul>

其中的process方法主要完成对request的解析,包括请求头、请求行和请求体 
代码清单3-11:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//process method of org.apache.coyote.http11.AbstractHttp11Processor<S>.HttpProcessor extends org.apache.coyote.http11.AbstractHttp11Processor<S></span>
    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> SocketState <span class="hljs-title" style="box-sizing: border-box;">process</span>(SocketWrapper<S> socketWrapper)
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> IOException {
        RequestInfo rp = request.getRequestProcessor();
        rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Setting up the I/O</span>
        setSocketWrapper(socketWrapper);
        getInputBuffer().init(socketWrapper, endpoint);
        getOutputBuffer().init(socketWrapper, endpoint);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Flags</span>
        error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
        comet = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        openSocket = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        sendfileInProgress = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        readComplete = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (endpoint.getUsePolling()) {
            keptAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            keptAlive = socketWrapper.isKeptAlive();
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (disableKeepAlive()) {
            socketWrapper.setKeepAliveLeft(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (!error && keepAlive && !comet && !isAsync() &&
                upgradeInbound == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> &&
                httpUpgradeHandler == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && !endpoint.isPaused()) {
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Parsing the request header</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                setRequestLineReadTimeout();
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!getInputBuffer().parseRequestLine(keptAlive)) {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (handleIncompleteRequestLineRead()) {
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
                    }
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (endpoint.isPaused()) {
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 503 - Service unavailable</span>
                    response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">503</span>);
                    error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Make sure that connectors that are non-blocking during</span>
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// header processing (NIO) only set the start time the first</span>
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// time a request is processed.</span>
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (request.getStartTime() < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                        request.setStartTime(System.currentTimeMillis());
                    }
                    keptAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Set this every time in case limit has been changed via JMX</span>
                    request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Currently only NIO will ever return false here</span>
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!getInputBuffer().parseHeaders()) {
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// We've read part of the request, don't recycle it</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// instead associate it with the socket</span>
                        openSocket = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                        readComplete = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
                    }
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!disableUploadTimeout) {
                        setSocketTimeout(connectionUploadTimeout);
                    }
                }
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IOException e) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isDebugEnabled()) {
                    getLog().debug(
                            sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.header.parse"</span>), e);
                }
                error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) {
                ExceptionUtils.handleThrowable(t);
                UserDataHelper.Mode logMode = userDataHelper.getNextMode();
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (logMode != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
                    String message = sm.getString(
                            <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.header.parse"</span>);
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (logMode) {
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> INFO_THEN_DEBUG:
                            message += sm.getString(
                                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.fallToDebug"</span>);
                            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//$FALL-THROUGH$</span>
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> INFO:
                            getLog().info(message);
                            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
                        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> DEBUG:
                            getLog().debug(message);
                    }
                }
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 400 - Bad Request</span>
                response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">400</span>);
                adapter.log(request, response, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
                error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!error) {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Setting up filters, and parse some request headers</span>
                rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                    prepareRequest();
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isDebugEnabled()) {
                        getLog().debug(sm.getString(
                                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.request.prepare"</span>), t);
                    }
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 400 - Internal Server Error</span>
                    response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">400</span>);
                    adapter.log(request, response, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
                    error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                }
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (maxKeepAliveRequests == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
                keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (maxKeepAliveRequests > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> &&
                    socketWrapper.decrementKeepAlive() <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
            }
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Process the request in the adapter</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!error) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
                    rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                    adapter.service(request, response);

                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(keepAlive && !error) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Avoid checking twice.</span>
                        error = response.getErrorException() != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ||
                                (!isAsync() &&
                                statusDropsConnection(response.getStatus()));
                    }
                    setCometTimeouts(socketWrapper);
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InterruptedIOException e) {
                    error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (HeadersTooLargeException e) {
                    error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// The response should not have been committed but check it</span>
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// anyway to be safe</span>
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!response.isCommitted()) {
                        response.reset();
                        response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">500</span>);
                        response.setHeader(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Connection"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"close"</span>);
                    }
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    getLog().error(sm.getString(
                            <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.request.process"</span>), t);
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 500 - Internal Server Error</span>
                    response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">500</span>);
                    adapter.log(request, response, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
                    error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
                }
            }
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Finish the handling of the request</span>
            rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!isAsync() && !comet) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (error) {

                    getInputBuffer().setSwallowInput(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (response.getStatus() < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span> || response.getStatus() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">299</span>) {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (expectation) {
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Client sent Expect: 100-continue but received a</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// non-2xx response. Disable keep-alive (if enabled) to</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ensure the connection is closed. Some clients may</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// still send the body, some may send the next request.</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// No way to differentiate, so close the connection to</span>
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// force the client to send the next request.</span>
                        getInputBuffer().setSwallowInput(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
                        keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
                    }
                }
                endRequest();
            }
            rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// If there was an error, make sure the request is counted as</span>
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// and error, and update the statistics counter</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (error) {
                response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">500</span>);
            }
            request.updateCounters();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!isAsync() && !comet || error) {
                getInputBuffer().nextRequest();
                getOutputBuffer().nextRequest();
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!disableUploadTimeout) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(endpoint.getSoTimeout() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
                    setSocketTimeout(endpoint.getSoTimeout());
                } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
                    setSocketTimeout(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
                }
            }
            rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (breakKeepAliveLoop(socketWrapper)) {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
            }
        }
        rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
        }
    }
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li><li style="box-sizing: border-box; padding: 0px 5px;">139</li><li style="box-sizing: border-box; padding: 0px 5px;">140</li><li style="box-sizing: border-box; padding: 0px 5px;">141</li><li style="box-sizing: border-box; padding: 0px 5px;">142</li><li style="box-sizing: border-box; padding: 0px 5px;">143</li><li style="box-sizing: border-box; padding: 0px 5px;">144</li><li style="box-sizing: border-box; padding: 0px 5px;">145</li><li style="box-sizing: border-box; padding: 0px 5px;">146</li><li style="box-sizing: border-box; padding: 0px 5px;">147</li><li style="box-sizing: border-box; padding: 0px 5px;">148</li><li style="box-sizing: border-box; padding: 0px 5px;">149</li><li style="box-sizing: border-box; padding: 0px 5px;">150</li><li style="box-sizing: border-box; padding: 0px 5px;">151</li><li style="box-sizing: border-box; padding: 0px 5px;">152</li><li style="box-sizing: border-box; padding: 0px 5px;">153</li><li style="box-sizing: border-box; padding: 0px 5px;">154</li><li style="box-sizing: border-box; padding: 0px 5px;">155</li><li style="box-sizing: border-box; padding: 0px 5px;">156</li><li style="box-sizing: border-box; padding: 0px 5px;">157</li><li style="box-sizing: border-box; padding: 0px 5px;">158</li><li style="box-sizing: border-box; padding: 0px 5px;">159</li><li style="box-sizing: border-box; padding: 0px 5px;">160</li><li style="box-sizing: border-box; padding: 0px 5px;">161</li><li style="box-sizing: border-box; padding: 0px 5px;">162</li><li style="box-sizing: border-box; padding: 0px 5px;">163</li><li style="box-sizing: border-box; padding: 0px 5px;">164</li><li style="box-sizing: border-box; padding: 0px 5px;">165</li><li style="box-sizing: border-box; padding: 0px 5px;">166</li><li style="box-sizing: border-box; padding: 0px 5px;">167</li><li style="box-sizing: border-box; padding: 0px 5px;">168</li><li style="box-sizing: border-box; padding: 0px 5px;">169</li><li style="box-sizing: border-box; padding: 0px 5px;">170</li><li style="box-sizing: border-box; padding: 0px 5px;">171</li><li style="box-sizing: border-box; padding: 0px 5px;">172</li><li style="box-sizing: border-box; padding: 0px 5px;">173</li><li style="box-sizing: border-box; padding: 0px 5px;">174</li><li style="box-sizing: border-box; padding: 0px 5px;">175</li><li style="box-sizing: border-box; padding: 0px 5px;">176</li><li style="box-sizing: border-box; padding: 0px 5px;">177</li><li style="box-sizing: border-box; padding: 0px 5px;">178</li><li style="box-sizing: border-box; padding: 0px 5px;">179</li><li style="box-sizing: border-box; padding: 0px 5px;">180</li><li style="box-sizing: border-box; padding: 0px 5px;">181</li><li style="box-sizing: border-box; padding: 0px 5px;">182</li><li style="box-sizing: border-box; padding: 0px 5px;">183</li><li style="box-sizing: border-box; padding: 0px 5px;">184</li><li style="box-sizing: border-box; padding: 0px 5px;">185</li><li style="box-sizing: border-box; padding: 0px 5px;">186</li><li style="box-sizing: border-box; padding: 0px 5px;">187</li><li style="box-sizing: border-box; padding: 0px 5px;">188</li><li style="box-sizing: border-box; padding: 0px 5px;">189</li><li style="box-sizing: border-box; padding: 0px 5px;">190</li><li style="box-sizing: border-box; padding: 0px 5px;">191</li><li style="box-sizing: border-box; padding: 0px 5px;">192</li><li style="box-sizing: border-box; padding: 0px 5px;">193</li><li style="box-sizing: border-box; padding: 0px 5px;">194</li><li style="box-sizing: border-box; padding: 0px 5px;">195</li><li style="box-sizing: border-box; padding: 0px 5px;">196</li></ul>

首先在Http11Processor的process方法里,会先从socket里读取http请求数据,并解析请求头,构造Request对象和Response对象,然后调用Adapter.service()方法。Adapter.service()完成请求行以及请求体的解析,并把解析出来的信息封装到Request和Response对象中,Adapter(确切说是org.apache.catalina.connector.CoyoteAdapter)是connector和container的桥梁,经过这一步,请求就从connector传递到container里了,Adapter.service()方法之后便将封装了Request以及Response对象的Socket传给Container容器了。 
要注意的是:最先处理请求的Request是org.apache.coyote.Request类型,这是一个Tomcat中一个轻量级对象,完成基本的请求处理后很容易被JVM回收,那为什么不直接交给Connector.Request对象处理呢?由于后者是Servlet容器真正传递的对象其完成的职责比前者复杂,这里使用org.apache.coyote.Request主要减轻后者的任务负担,出于性能考虑才这么设计。 
具体service方法清单如下:

代码清单3-12:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@Override
public void service(org<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.apache</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.coyote</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Request</span> req,
                      org<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.apache</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.coyote</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Response</span> res)
      throws Exception {
      Request request = (Request) req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getNote</span>(ADAPTER_NOTES)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
      Response response = (Response) res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getNote</span>(ADAPTER_NOTES)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
      if (request == null) {
          // Create objects
          request = connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.createRequest</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCoyoteRequest</span>(req)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          response = connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.createResponse</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCoyoteResponse</span>(res)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          // Link objects
          request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setResponse</span>(response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setRequest</span>(request)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Set</span> as notes
          req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setNote</span>(ADAPTER_NOTES, request)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setNote</span>(ADAPTER_NOTES, response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Set</span> query string encoding
          req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getParameters</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setQueryStringEncoding</span>
              (connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getURIEncoding</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
      }
      if (connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getXpoweredBy</span>()) {
          response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addHeader</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"X-Powered-By"</span>, POWERED_BY)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
      }
      boolean comet = false<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
      boolean async = false<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
      try {
 // Parse <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span> Catalina <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> configuration //specific
          // request parameters
          req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getRequestProcessor</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setWorkerThreadName</span>(Thread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.currentThread</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          //postParseRequest方法把CoyoteRequest转换为Connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Request</span>对象
          //后一类型的对象才是在Tomcat容器流转时真正传递的对象
          boolean postParseSuccess = postParseRequest(req, request, res, response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          if (postParseSuccess) {
              //check valves if we support async
              request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setAsyncSupported</span>(connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getService</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getContainer</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getPipeline</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isAsyncSupported</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    // 调用Container容器的invoke方法,把请求交给Container容器
              connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getService</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getContainer</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getPipeline</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getFirst</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.invoke</span>(request, response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
              if (request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isComet</span>()) {
                  if (!response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isClosed</span>() && !response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isError</span>()) {
                      if (request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAvailable</span>() || (request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getContentLength</span>() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && (!request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isParametersParsed</span>()))) {
                          // Invoke a read event right away if there are available bytes
                          if (event(req, res, SocketStatus<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.OPEN</span>_READ)) {
                              comet = true<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                              res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.action</span>(ActionCode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.COMET</span>_BEGIN, null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                          }
                      } else {
                          comet = true<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                          res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.action</span>(ActionCode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.COMET</span>_BEGIN, null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                      }
                  } else {
                      // Clear the filter chain, as otherwise it will not be reset elsewhere
                      // since this is a Comet request
                      request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setFilterChain</span>(null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                  }
              }
          }
          AsyncContextImpl asyncConImpl = (AsyncContextImpl)request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAsyncContext</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          if (asyncConImpl != null) {
              async = true<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          } else if (!comet) {
              request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.finishRequest</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
              response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.finishResponse</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
              if (postParseSuccess &&
                      request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getMappingData</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.context</span> != null) {
                  ((Context) request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getMappingData</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.context</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.logAccess</span>(
                          request, response,
                          System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.currentTimeMillis</span>() - req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getStartTime</span>(),
                          false)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
              }
              req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.action</span>(ActionCode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.POST</span>_REQUEST , null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
          }
      } catch (IOException e) {
          // Ignore
      } finally {
         //ignore
      }
  }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li></ul>

connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);这句代码中可以知道下一步的处理需要交给Container容器了。

经过上面一系列复杂的操作流程,Tomcat的Connector已经完成了protocol.start()方法,返回Connector的startIntenal方法,还有一个步骤要完成就是mapperListener.start()的方法了,整个执行过程比较简单,有两步:

  1. 执行Connector的startIntenal方法
  2. 执行MapperListener的startIntenal方法

代码清单3-14:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> LifecycleException {
        setState(LifecycleState.STARTING);
        findDefaultHost();
        Engine engine = (Engine) connector.getService().getContainer();
        addListeners(engine);
        Container[] conHosts = engine.findChildren();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Container conHost : conHosts) {
            Host host = (Host) conHost;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!LifecycleState.NEW.equals(host.getState())) {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Registering the host will register the context and wrappers</span>
                registerHost(host);
            }
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>

首先注册已初始化的组件,然后为这些组件添加监听器,最后添加容器之间的映射关系。这样经过上面两个大步骤以及N个小步骤,我们的Connector才算启动完毕,可谓是路途艰辛啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值