1. 程式人生 > >Tomcat原始碼閱讀之初始化聯結器元件

Tomcat原始碼閱讀之初始化聯結器元件

Server元件初始化之後,接著就該初始化Service元件。

public void initialize()
            throws LifecycleException
    {

        initialized = true;
                    。
                    。
                    。
                    略
        // Initialize our defined Connectors
        synchronized (connectors) {
            for
(int i = 0; i < connectors.length; i++) { try { connectors[i].initialize(); } catch (Exception e) { String message = sm.getString( "standardService.connector.initFailed", connectors[i]); log.error(message, e); if
(Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) throw new LifecycleException(message); } } } }

Service元件初始化的過程比較簡單,首先將initialized 的值置為true,然後註冊JMX服務,除此之外沒有其他的操作。
一個Service元件可以包含多個聯結器元件,那麼接著看聯結器元件的初始化。
Connector類的initialize方法主要做了三件事,首先將initialized的值置為true,接著將Connector物件傳給CoyoteAdapter,並例項化CoyoteAdapter類,CoyoteAdapter類的作用會在講解處理請求的過程中詳細介紹。最後呼叫ProtocolHandler實現類的init方法。
ProtocolHandler介面的作用是管理網路連線的狀態,介面中定義了init,start,destroy等方法,分別用於初始化聯結器,啟動接收請求執行緒並使其處於監聽狀態和關閉Socket連線等操作。Tomcat預設使用的協議是HTTP/1.1,因此,這裡用到的類是Http11Protocol,那麼接著看Http11Protocol類的init方法。
Http11Protocol的init方法中,設定完連線的名稱和連線處理器之後,呼叫JIoEndpoint的init繼續進行初始化。
可以看出前面Connector和Http11Protocol類的init方法邏輯都比較簡單,其作用是在為後面真正的初始化操作做鋪墊,而正真執行聯結器初始化的操作是在JIoEndpoint的init方法中。

  public void init()
        throws Exception {

        if (initialized)
            return;

        // Initialize thread count defaults for acceptor
        if (acceptorThreadCount == 0) {
            acceptorThreadCount = 1;
        }
        if (serverSocketFactory == null) {
            serverSocketFactory = ServerSocketFactory.getDefault();
        }
        if (serverSocket == null) {
            try {
                if (address == null) {
                    serverSocket = serverSocketFactory.createSocket(port, backlog);
                } else {
                    serverSocket = serverSocketFactory.createSocket(port, backlog, address);
                }
            } catch (BindException orig) {
                String msg;
                if (address == null)
                    msg = orig.getMessage() + " <null>:" + port;
                else
                    msg = orig.getMessage() + " " +
                            address.toString() + ":" + port;
                BindException be = new BindException(msg);
                be.initCause(orig);
                throw be;
            }
        }
        //if( serverTimeout >= 0 )
        //    serverSocket.setSoTimeout( serverTimeout );

        initialized = true;

在init方法中,首先初始化acceptorThreadCount 的值,如果值為0的話則置為1。
acceptorThreadCount 的值代表需要啟動的接收執行緒的數量,在啟動接收執行緒的時候會用到。接著例項化Socket工廠物件,預設使用的是DefaultServerSocketFactory類。有了工廠物件之後就可以通過工廠物件來建立Socket物件了,到這一步Tomcat的初始化過程算是執行完了,關於Sokcet物件啟動監聽,接收請求,那是後面的start過程了。未完待續。。。。。。