Tomcat源码分析(十三) -- ProtocolHandler

331 阅读1分钟

Tomcat 中的 ProtocolHandler

ProtocolHandler 定义

public interface ProtocolHandler {

    public Adapter getAdapter();

    public void setAdapter(Adapter adapter);

    public Executor getExecutor();

    public void init() throws Exception;

    public void start() throws Exception;

    public void pause() throws Exception;

    public void resume() throws Exception;

    public void stop() throws Exception;

    public void destroy() throws Exception;

    public void closeServerSocketGraceful();

    public boolean isAprRequired();

    public boolean isSendfileSupported();


    public void addSslHostConfig(SSLHostConfig sslHostConfig);
    public SSLHostConfig[] findSslHostConfigs();


    public void addUpgradeProtocol(UpgradeProtocol upgradeProtocol);
    public UpgradeProtocol[] findUpgradeProtocols();
}
  • ProtocolHandler 中包含了一个Adapter,在Connector 中为ProtocolHandler 设置了一个CoyoteAdapter
  • ProtocolHandler 中定义了一系列操作方法
  • ProtocolHandler 的实现类 AbstractHttp11Protocol

AbstractHttp11Protocol 的 init 方法

public void init() throws Exception {
    // Upgrade protocols have to be configured first since the endpoint
    // init (triggered via super.init() below) uses this list to configure
    // the list of ALPN protocols to advertise
    for (UpgradeProtocol upgradeProtocol : upgradeProtocols) {
        configureUpgradeProtocol(upgradeProtocol);
    }
    //进入父类 AbstractProtocol 的 initial 方法
    super.init();
}

AbstractProtocol 的 init 方法

public void init() throws Exception {
    if (getLog().isInfoEnabled()) {
        getLog().info(sm.getString("abstractProtocolHandler.init", getName()));
    }

    if (oname == null) {
        // Component not pre-registered so register it
        oname = createObjectName();//获取协议和端口号
        if (oname != null) {
            Registry.getRegistry(null, null).registerComponent(this, oname, null);
        }
    }

    if (this.domain != null) {
        rgOname = new ObjectName(domain + ":type=GlobalRequestProcessor,name=" + getName());
        Registry.getRegistry(null, null).registerComponent(
            getHandler().getGlobal(), rgOname, null);
    }

    //设置 endpoint 的属性
    String endpointName = getName();
    endpoint.setName(endpointName.substring(1, endpointName.length()-1));
    endpoint.setDomain(domain);
    //这里调用 Endpoint 的initial方法
    //进入 org.apache.tomcat.util.net.AbstractEndpoint 的 init 方法
    endpoint.init();
}

AbstractProtocol 的 start 方法

public void start() throws Exception {
    if (getLog().isInfoEnabled()) {
        getLog().info(sm.getString("abstractProtocolHandler.start", getName()));
    }
    //调用 endpoint 的 start 方法
    endpoint.start();

    // Start timeout thread
    //这里有一个超时的线程,超时机制是这样的--直接跑一个线程来监听
    asyncTimeout = new AsyncTimeout();
    Thread timeoutThread = new Thread(asyncTimeout, getNameInternal() + "-AsyncTimeout");
    int priority = endpoint.getThreadPriority();
    if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
        priority = Thread.NORM_PRIORITY;
    }
    timeoutThread.setPriority(priority);
    timeoutThread.setDaemon(true);
    timeoutThread.start();
}

AbstractProtocol 的 stop 方法

public void stop() throws Exception {
    if(getLog().isInfoEnabled()) {
        getLog().info(sm.getString("abstractProtocolHandler.stop", getName()));
    }
    //先停止超时线程
    if (asyncTimeout != null) {
        asyncTimeout.stop();
    }
    //调用 endpoint 的 stop 方法
    endpoint.stop();
}

AbstractProtocol 的 destroy方法

 public void destroy() throws Exception {
     if(getLog().isInfoEnabled()) {
         getLog().info(sm.getString("abstractProtocolHandler.destroy", getName()));
     }

     try {
         //调用 endpoint 的  destroy 方法
         endpoint.destroy();
     } finally {
         if (oname != null) {
             if (mserver == null) {
                 Registry.getRegistry(null, null).unregisterComponent(oname);
             } else {
                 // Possibly registered with a different MBeanServer
                 try {
                     mserver.unregisterMBean(oname);
                 } catch (MBeanRegistrationException | InstanceNotFoundException e) {
                     getLog().info(sm.getString("abstractProtocol.mbeanDeregistrationFailed",
                                                oname, mserver));
                 }
             }
         }

         if (rgOname != null) {
             Registry.getRegistry(null, null).unregisterComponent(rgOname);
         }
     }
 }

小结

  • ProtocolHandler 的操作都是基于 AbstractEndpoint 对象的