标签:哪些 消息 也会 otherwise errors processor rest settings 怎样
终于进行到Connector的分析阶段了,这也是Tomcat里面最复杂的一块功能了。Connector中文名为连接器,既然是连接器,它肯定会连接某些东西,连接些什么呢?connector组件的processor对象处理的request和response,connector有三种request和response对象:coyoteRequest和coyoteResponse(是专门用于Tomcat内部表示,和servlet无关),Catalina(实现了servlet规范,将上面的coyote的那对request和response适配成Catalina包下的request和response),facade(作用是做Catalina包下面的那对request和response的门面,也部分实现servlet的规范,还有其他public方法,但是不暴露出去)
Connector用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后再交给Connector返回给客户端。
要理解Connector,我们需要问自己4个问题。
Connector如何接受请求的?Container进行处理的?Container处理完之后如何交给Connector并返回给客户端的?先来一张Connector的整体结构图

【注意】:不同的协议、不同的通信方式,ProtocolHandler会有不同的实现。在Tomcat8.5中,ProtocolHandler的类继承层级如下图所示。

针对上述的类继承层级图,我们做如下说明:
ProtocolHandler包含三个部件:Endpoint、Processor、Adapter。
Endpoint用来处理底层Socket的网络连接,Processor用于将Endpoint接收到的Socket封装成Request,Adapter用于将Request交给Container进行具体的处理。Endpoint由于是处理底层的Socket网络连接,因此Endpoint是用来实现TCP/IP协议的,而Processor用来实现HTTP协议的,Adapter将请求适配到Servlet容器进行具体的处理。Endpoint的抽象实现类AbstractEndpoint里面定义了Acceptor和AsyncTimeout两个内部类和一个Handler接口。Acceptor用于监听请求,AsyncTimeout用于检查异步Request的超时,Handler用于处理接收到的Socket,在内部调用Processor进行处理。至此,我们已经明白了问题(1)、(2)和(3)。至于(4),当我们了解了Container自然就明白了,前面章节内容已经详细分析过了。
我们在Service标准实现StandardService的源码中发现,其init()、start()、stop()和destroy()方法分别会对Connectors的同名方法进行调用。而一个Service对应着多个Connector。限于篇幅,本章不再罗列这部分代码,需要读者自行阅读tomcat源码。
【注】:本章我们仅对
http1.1协议且nio通信方式的相关代码进行分析。
我们知道Connector实现了Lifecycle接口,所以它是一个生命周期组件。所以Connector的启动逻辑入口在于init()和start()。
在分析之前,我们看看server.xml,该文件已经体现出了tomcat中各个组件的大体结构。
<?xml version=‘1.0‘ encoding=‘utf-8‘?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt