Tomcat源碼解析系列(十)Connector

前言
在前幾篇文章()中,介紹了 Tomcat 中 Container 及其相關組件,包括 Engine、Host、Context、Wrapper、Pipeline 和 Valve。在這篇文章中分析到了 Service 的 initInternal 和 startInternal 方法,在其中就調用了 Connector 的 init 和 start 方法。Connector 繼承自 LifecycleMBeanBase。apache


1. Connector 構造方法segmentfault

/**
 * Defaults to using HTTP/1.1 NIO implementation.
 */
public Connector() {
    this("org.apache.coyote.http11.Http11NioProtocol");
}


public Connector(String protocol) {
    boolean aprConnector = AprLifecycleListener.isAprAvailable() &&
            AprLifecycleListener.getUseAprConnector();

    if ("HTTP/1.1".equals(protocol) || protocol == null) {
        if (aprConnector) {
            protocolHandlerClassName = "org.apache.coyote.http11.Http11AprProtocol";
        } else {
            protocolHandlerClassName = "org.apache.coyote.http11.Http11NioProtocol";
        }
    } else if ("AJP/1.3".equals(protocol)) {
        if (aprConnector) {
            protocolHandlerClassName = "org.apache.coyote.ajp.AjpAprProtocol";
        } else {
            protocolHandlerClassName = "org.apache.coyote.ajp.AjpNioProtocol";
        }
    } else {
        protocolHandlerClassName = protocol;
    }

    // Instantiate protocol handler
    ProtocolHandler p = null;
    try {
        Class<?> clazz = Class.forName(protocolHandlerClassName);
        p = (ProtocolHandler) clazz.getConstructor().newInstance();
    } catch (Exception e) {
        log.error(sm.getString(
                "coyoteConnector.protocolHandlerInstantiationFailed"), e);
    } finally {
        this.protocolHandler = p;
    }

    // Default for Connector depends on this system property
    setThrowOnFailure(Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"));
}

在構造方法中,根據配置建立了一個 ProtocolHandler 對象,並把它賦值得 protocolHandler 屬性。能夠看出,ProtocolHandler 的默認實現類是 Http11NioProtocol。
2. Connector#initInternal 方法app

@Override
protected void initInternal() throws LifecycleException {

    super.initInternal();

    if (protocolHandler == null) {
        throw new LifecycleException(
                sm.getString("coyoteConnector.protocolHandlerInstantiationFailed"));
    }

    // Initialize adapter
    adapter = new CoyoteAdapter(this);
    protocolHandler.setAdapter(adapter);
    if (service != null) {
        protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor());
    }

    // Make sure parseBodyMethodsSet has a default
    if (null == parseBodyMethodsSet) {
        setParseBodyMethods(getParseBodyMethods());
    }

    if (protocolHandler.isAprRequired() && !AprLifecycleListener.isInstanceCreated()) {
        throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprListener",
                getProtocolHandlerClassName()));
    }
    if (protocolHandler.isAprRequired() && !AprLifecycleListener.isAprAvailable()) {
        throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprLibrary",
                getProtocolHandlerClassName()));
    }
    if (AprLifecycleListener.isAprAvailable() && AprLifecycleListener.getUseOpenSSL() &&
            protocolHandler instanceof AbstractHttp11JsseProtocol) {
        AbstractHttp11JsseProtocol<?> jsseProtocolHandler =
                (AbstractHttp11JsseProtocol<?>) protocolHandler;
        if (jsseProtocolHandler.isSSLEnabled() &&
                jsseProtocolHandler.getSslImplementationName() == null) {
            // OpenSSL is compatible with the JSSE configuration, so use it if APR is available
            jsseProtocolHandler.setSslImplementationName(OpenSSLImplementation.class.getName());
        }
    }

    try {
        protocolHandler.init();
    } catch (Exception e) {
        throw new LifecycleException(
                sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e);
    }
}

在 initInternal 裏,首先建立了一個 CoyoteAdapter 對象,並調用 protocolHandler.setAdapter(adapter),把這個 CoyoteAdapter 對象賦值給 protocolHandler 的 Adapter 類型的 adapter 屬性(在 protocolHandler 的實現類的父類 AbstractProtocol 裏)。這個 Adapter 對象是 ProtocolHandler 用來處理請求的。
而後對 ProtocolHandler 的屬性作了一些設值。
最後調用了 ProtocolHandler#init 方法。
ProtocolHandler 是 Connector 用來處理鏈接和請求的很是關鍵的組件。後面會單獨分析。
3. Connector#startInternal 方法ide

@Override
protected void startInternal() throws LifecycleException {

    // Validate settings before starting
    if (getPortWithOffset() < 0) {
        throw new LifecycleException(sm.getString(
                "coyoteConnector.invalidPort", Integer.valueOf(getPortWithOffset())));
    }

    setState(LifecycleState.STARTING);

    try {
        protocolHandler.start();
    } catch (Exception e) {
        throw new LifecycleException(
                sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);
    }
}

Connector#startInternal 裏最主要的就是調用 ProtocolHandler#init 方法。ui

小結
本文分析了 Connector 的初始化和啓動過程,能夠看出,最重要的步驟就是初始化並啓動了 ProtocolHandler。this

相關文章
相關標籤/搜索