亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

How Tomcat Works(五)

系統 2416 0

本文接下來介紹tomcat的默認連接器,Tomcat中的默認連接器必須滿足以下要求:

  • 實現org.apache.catalina.Connector接口

  • 負責創建實現org.apache.catalina.Request接口的Request對象

  • 負責創建實現org.apache.catalina.Response接口的Response對象

org.apache.catalina.Connector接口最重要的方法是getContainer() 、setContainer()、creatRequest()、 creatResponse(),setContainer()方法用于設置相關聯的servlet容器,getContainer()方法獲取相關連的servlet容器,creatRequest()方法為http請求創建request對象,creatResponse()方法創建response對象

下面來分析HttpConnector類實現,HttpConnector類同時實現了org.apache.catalina.Connector接口org.apache.catalina.Lifecycle接口(用于生命周期管理)、java.lang.Runnable接口(多線程接口)

在HttpConnector對象的初始化方法initialize()里面,調用私有方法open(),創建ServerSocket實例

      
        private
      
      
         ServerSocket open()
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException
    {

        
      
      
        //
      
      
         Acquire the server socket factory for this Connector
      
      
        ServerSocketFactory factory =
      
         getFactory();

        
      
      
        //
      
      
         If no address is specified, open a connection on all addresses
      
      
        if
      
       (address == 
      
        null
      
      
        ) {
            log(sm.getString(
      
      "httpConnector.allAddresses"
      
        ));
            
      
      
        try
      
      
         {
                
      
      
        return
      
      
         (factory.createSocket(port, acceptCount));
            } 
      
      
        catch
      
      
         (BindException be) {
                
      
      
        throw
      
      
        new
      
       BindException(be.getMessage() + ":" +
      
         port);
            }
        }

        
      
      
        //
      
      
         Open a server socket on the specified address
      
      
        try
      
      
         {
            InetAddress is 
      
      =
      
         InetAddress.getByName(address);
            log(sm.getString(
      
      "httpConnector.anAddress"
      
        , address));
            
      
      
        try
      
      
         {
                
      
      
        return
      
      
         (factory.createSocket(port, acceptCount, is));
            } 
      
      
        catch
      
      
         (BindException be) {
                
      
      
        throw
      
      
        new
      
       BindException(be.getMessage() + ":" + address +
                                        ":" +
      
         port);
            }
        } 
      
      
        catch
      
      
         (Exception e) {
            log(sm.getString(
      
      "httpConnector.noAddress"
      
        , address));
            
      
      
        try
      
      
         {
                
      
      
        return
      
      
         (factory.createSocket(port, acceptCount));
            } 
      
      
        catch
      
      
         (BindException be) {
                
      
      
        throw
      
      
        new
      
       BindException(be.getMessage() + ":" +
      
         port);
            }
        }

    }
      
    

上面的ServerSocketFactory factory = getFactory()顯然是創建ServerSocket實例的工廠,方法如下

      
        /**
      
      
        
     * Return the server socket factory used by this Container.
     
      
      
        */
      
      
        public
      
      
         ServerSocketFactory getFactory() {

        
      
      
        if
      
       (
      
        this
      
      .factory == 
      
        null
      
      
        ) {
            
      
      
        synchronized
      
       (
      
        this
      
      
        ) {
                
      
      
        this
      
      .factory = 
      
        new
      
      
         DefaultServerSocketFactory();
            }
        }
        
      
      
        return
      
       (
      
        this
      
      
        .factory);

    }
      
    

工廠類DefaultServerSocketFactory實現了ServerSocketFactory接口

      
        public
      
      
        final
      
      
        class
      
       DefaultServerSocketFactory 
      
        implements
      
      
         ServerSocketFactory {
   
      
      
        public
      
       ServerSocket createSocket (
      
        int
      
      
         port)
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException {

        
      
      
        return
      
       (
      
        new
      
      
         ServerSocket(port));

    }
   
      
      
        public
      
       ServerSocket createSocket (
      
        int
      
       port, 
      
        int
      
      
         backlog)
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException {

        
      
      
        return
      
       (
      
        new
      
      
         ServerSocket(port, backlog));

    }
    
      
      
        public
      
       ServerSocket createSocket (
      
        int
      
       port, 
      
        int
      
      
         backlog,
                                      InetAddress ifAddress)
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException {

        
      
      
        return
      
       (
      
        new
      
      
         ServerSocket(port, backlog, ifAddress));

    }

}
      
    

下面接著分析用于生命周期的start()方法

      
        /**
      
      
        
     * Begin processing requests via this Connector.
     *
     * 
      
      
        @exception
      
      
         LifecycleException if a fatal startup error occurs
     
      
      
        */
      
      
        public
      
      
        void
      
       start() 
      
        throws
      
      
         LifecycleException {

        
      
      
        //
      
      
         Validate and update our current state
      
      
        if
      
      
         (started)
            
      
      
        throw
      
      
        new
      
      
         LifecycleException
                (sm.getString(
      
      "httpConnector.alreadyStarted"
      
        ));
        threadName 
      
      = "HttpConnector[" + port + "]"
      
        ;
        lifecycle.fireLifecycleEvent(START_EVENT, 
      
      
        null
      
      
        );
        started 
      
      = 
      
        true
      
      
        ;

        
      
      
        //
      
      
         Start our background thread
      
      
                threadStart();

        
      
      
        //
      
      
         Create the specified minimum number of processors
      
      
        while
      
       (curProcessors <
      
         minProcessors) {
            
      
      
        if
      
       ((maxProcessors > 0) && (curProcessors >=
      
         maxProcessors))
                
      
      
        break
      
      
        ;
            HttpProcessor processor 
      
      =
      
         newProcessor();
            recycle(processor);
        }

    }
      
    

首先是啟動HttpConnector連接器線程,然后是初始化最少數量的HttpProcessor處理器入棧

      
        /**
      
      
        
     * Start the background processing thread.
     
      
      
        */
      
      
        private
      
      
        void
      
      
         threadStart() {

        log(sm.getString(
      
      "httpConnector.starting"
      
        ));

        thread 
      
      = 
      
        new
      
       Thread(
      
        this
      
      
        , threadName);
        thread.setDaemon(
      
      
        true
      
      
        );
        thread.start();

    }
      
    

由于HttpConnector連接器實現了java.lang.Runnable接口,我們分析它的run()方法實現

      
        /**
      
      
        
     * The background thread that listens for incoming TCP/IP connections and
     * hands them off to an appropriate processor.
     
      
      
        */
      
      
        public
      
      
        void
      
      
         run() {
        
      
      
        //
      
      
         Loop until we receive a shutdown command
      
      
        while
      
       (!
      
        stopped) {
            
      
      
        //
      
      
         Accept the next incoming connection from the server socket
      
      
            Socket socket = 
      
        null
      
      
        ;
            
      
      
        try
      
      
         {
                
      
      
        //
      
      
                        if (debug >= 3)
                
      
      
        //
      
      
                            log("run: Waiting on serverSocket.accept()");
      
      
                socket =
      
         serverSocket.accept();
                
      
      
        //
      
      
                        if (debug >= 3)
                
      
      
        //
      
      
                            log("run: Returned from serverSocket.accept()");
      
      
        if
      
       (connectionTimeout > 0
      
        )
                    socket.setSoTimeout(connectionTimeout);
                socket.setTcpNoDelay(tcpNoDelay);
            } 
      
      
        catch
      
      
         (AccessControlException ace) {
                log(
      
      "socket accept security exception"
      
        , ace);
                
      
      
        continue
      
      
        ;
            } 
      
      
        catch
      
      
         (IOException e) {
                
      
      
        //
      
      
                        if (debug >= 3)
                
      
      
        //
      
      
                            log("run: Accept returned IOException", e);
      
      
        try
      
      
         {
                    
      
      
        //
      
      
         If reopening fails, exit
      
      
        synchronized
      
      
         (threadSync) {
                        
      
      
        if
      
       (started && !
      
        stopped)
                            log(
      
      "accept error: "
      
        , e);
                        
      
      
        if
      
       (!
      
        stopped) {
                            
      
      
        //
      
      
                            if (debug >= 3)
                            
      
      
        //
      
      
                                log("run: Closing server socket");
      
      
                                    serverSocket.close();
                            
      
      
        //
      
      
                                if (debug >= 3)
                            
      
      
        //
      
      
                                    log("run: Reopening server socket");
      
      
                            serverSocket =
      
         open();
                        }
                    }
                    
      
      
        //
      
      
                            if (debug >= 3)
                    
      
      
        //
      
      
                                log("run: IOException processing completed");
      
      
                } 
      
        catch
      
      
         (IOException ioe) {
                    log(
      
      "socket reopen, io problem: "
      
        , ioe);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (KeyStoreException kse) {
                    log(
      
      "socket reopen, keystore problem: "
      
        , kse);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (NoSuchAlgorithmException nsae) {
                    log(
      
      "socket reopen, keystore algorithm problem: "
      
        , nsae);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (CertificateException ce) {
                    log(
      
      "socket reopen, certificate problem: "
      
        , ce);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (UnrecoverableKeyException uke) {
                    log(
      
      "socket reopen, unrecoverable key: "
      
        , uke);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (KeyManagementException kme) {
                    log(
      
      "socket reopen, key management problem: "
      
        , kme);
                    
      
      
        break
      
      
        ;
                }

                
      
      
        continue
      
      
        ;
            }

            
      
      
        //
      
      
         Hand this socket off to an appropriate processor
      
      
            HttpProcessor processor =
      
         createProcessor();
            
      
      
        if
      
       (processor == 
      
        null
      
      
        ) {
                
      
      
        try
      
      
         {
                    log(sm.getString(
      
      "httpConnector.noProcessor"
      
        ));
                    socket.close();
                } 
      
      
        catch
      
      
         (IOException e) {
                    ;
                }
                
      
      
        continue
      
      
        ;
            }
            
      
      
        //
      
      
                    if (debug >= 3)
            
      
      
        //
      
      
                        log("run: Assigning socket to processor " + processor);
      
      
                    processor.assign(socket);

            
      
      
        //
      
      
         The processor will recycle itself when it finishes
      
      
        
        }

        
      
      
        //
      
      
         Notify the threadStop() method that we have shut ourselves down
        
      
      
        //
      
      
                if (debug >= 3)
        
      
      
        //
      
      
                    log("run: Notifying threadStop() that we have shut down");
      
      
        synchronized
      
      
         (threadSync) {
            threadSync.notifyAll();
        }

    }
      
    

上面方法中,監聽客戶端的http請求,當監聽到http請求時,獲取Socket實例,然后委派給HttpProcessor對象進行處理(處理器線程吧),最后是如果收到停止連接器線程命令, 則事件通知可以停止線程了

在上面我們還沒有來得及分析HttpProcessor對象的初始化相關,所以要重新回到start()方法(源碼分析有時要跟蹤方法中對多個其他方法的調用,深度優先則顧此失彼,難以兼顧;而廣度優先則不便縱向深入)

      
        //
      
      
         Create the specified minimum number of processors
      
      
        while
      
       (curProcessors <
      
         minProcessors) {
            
      
      
        if
      
       ((maxProcessors > 0) && (curProcessors >=
      
         maxProcessors))
                
      
      
        break
      
      
        ;
            HttpProcessor processor 
      
      =
      
         newProcessor();
            recycle(processor);
        }
      
    

這里是創建最少數量的HttpProcessor處理器并入棧,我們先分析newProcessor()方法的實現

      
        /**
      
      
        
     * Create and return a new processor suitable for processing HTTP
     * requests and returning the corresponding responses.
     
      
      
        */
      
      
        private
      
      
         HttpProcessor newProcessor() {

        
      
      
        //
      
      
                if (debug >= 2)
        
      
      
        //
      
      
                    log("newProcessor: Creating new processor");
      
      
        HttpProcessor processor = 
      
        new
      
       HttpProcessor(
      
        this
      
      , curProcessors++
      
        );
        
      
      
        if
      
       (processor 
      
        instanceof
      
      
         Lifecycle) {
            
      
      
        try
      
      
         {
                ((Lifecycle) processor).start();
            } 
      
      
        catch
      
      
         (LifecycleException e) {
                log(
      
      "newProcessor"
      
        , e);
                
      
      
        return
      
       (
      
        null
      
      
        );
            }
        }
        created.addElement(processor);
        
      
      
        return
      
      
         (processor);

    }
      
    

我們可以看到,這里主要是實例化HttpProcessor對象,傳入HttpConnector實例本身(里面要用到HttpConnector對象的創建Request對象方法和創建Response對象方法),然后向上轉型為Lifecycle接口類型,并調用它的start()方法,接著Vector created = new Vector()成員變量添加該HttpProcessor對象(Vector實現List接口,內部采用數組實現,其操作方法支持線程同步),最后返回實例

      
        /**
      
      
        
     * Recycle the specified Processor so that it can be used again.
     *
     * 
      
      
        @param
      
      
         processor The processor to be recycled
     
      
      
        */
      
      
        void
      
      
         recycle(HttpProcessor processor) {

        
      
      
        //
      
      
                if (debug >= 2)
        
      
      
        //
      
      
                    log("recycle: Recycling processor " + processor);
      
      
                processors.push(processor);

    }
      
    

這里將HttpProcessor對象入棧,成員變量Stack processors = new Stack()繼承自 Vector ,是一種先進后出的數據結構

我們現在來分析run()方法里面的相關源碼,也許更容易理解

      
        /**
      
      
        
     * Create (or allocate) and return an available processor for use in
     * processing a specific HTTP request, if possible.  If the maximum
     * allowed processors have already been created and are in use, return
     * <code>null</code> instead.
     
      
      
        */
      
      
        private
      
      
         HttpProcessor createProcessor() {

        
      
      
        synchronized
      
      
         (processors) {
            
      
      
        if
      
       (processors.size() > 0
      
        ) {
                
      
      
        //
      
      
         if (debug >= 2)
                
      
      
        //
      
      
         log("createProcessor: Reusing existing processor");
      
      
        return
      
      
         ((HttpProcessor) processors.pop());
            }
            
      
      
        if
      
       ((maxProcessors > 0) && (curProcessors <
      
         maxProcessors)) {
                
      
      
        //
      
      
         if (debug >= 2)
                
      
      
        //
      
      
         log("createProcessor: Creating new processor");
      
      
        return
      
      
         (newProcessor());
            } 
      
      
        else
      
      
         {
                
      
      
        if
      
       (maxProcessors < 0
      
        ) {
                    
      
      
        //
      
      
         if (debug >= 2)
                    
      
      
        //
      
      
         log("createProcessor: Creating new processor");
      
      
        return
      
      
         (newProcessor());
                } 
      
      
        else
      
      
         {
                    
      
      
        //
      
      
         if (debug >= 2)
                    
      
      
        //
      
      
         log("createProcessor: Cannot create new processor");
      
      
        return
      
       (
      
        null
      
      
        );
                }
            }
        }

    }
      
    

這里是從Stack processors = new Stack()成員變量里面獲取HttpProcessor對象 ,后面的代碼不用多加解釋了吧,你懂的!

后面那段代碼是干嘛的

      
        //
      
      
         Notify the threadStop() method that we have shut ourselves down
        
      
      
        //
      
      
                if (debug >= 3)
        
      
      
        //
      
      
                    log("run: Notifying threadStop() that we have shut down");
      
      
        synchronized
      
      
         (threadSync) {
            threadSync.notifyAll();
        }
      
    

我們看到threadStop()方法里面的代碼,可以看出上面的代碼塊是用來通知線程停止的

      
        /**
      
      
        
     * Stop the background processing thread.
     
      
      
        */
      
      
        private
      
      
        void
      
      
         threadStop() {

        log(sm.getString(
      
      "httpConnector.stopping"
      
        ));

        stopped 
      
      = 
      
        true
      
      
        ;
        
      
      
        try
      
      
         {
            threadSync.wait(
      
      5000
      
        );
        } 
      
      
        catch
      
      
         (InterruptedException e) {
            ;
        }
        thread 
      
      = 
      
        null
      
      
        ;

    }
      
    

由于HttpProcessor處理器類的源碼分析相對獨立,加上篇幅還比較多,因此本文先到這里,下文繼續……

---------------------------------------------------------------------------?

本系列How Tomcat Works系本人原創?

轉載請注明出處 博客園 刺猬的溫馴?

本人郵箱: chenying998179 # 163.com ( #改為@

本文鏈接 http://www.cnblogs.com/chenying99/p/3235530.html

How Tomcat Works(五)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 四虎国产精品永久在线播放 | 91精品国产色综合久久不 | 极品美女aⅴ高清在线观看 极品美女一级毛片 | 热久久精品在线 | 男人资源在线观看 | 日日夜夜欧美 | 亚洲精品一区二区三区不卡 | 日本不卡影院 | 国产亚洲精品久久久久久小说 | 欧美综合成人网 | 欧美91精品久久久久网免费 | 爱视频福利网 | 亚洲欧美日韩v中文在线 | 国产精品日韩欧美一区二区 | 色婷婷在线观看视频 | 四虎国产精品永久地址51 | 91蝌蚪在线播放 | 亚洲热在线 | 四虎国产精品影库永久免费 | 免费观看欧美成人禁片 | 欧美顶级xxxxbbbb| 亚洲日本一区二区三区高清在线 | 日日撸夜夜撸网站 | 欧美亚洲日本国产 | 四虎永久影院永久影库 | 一级片免费视频 | 四虎永久免费在线观看 | 国产亚洲欧美另类一区二区三区 | 国内精品久久久久久久亚洲 | 五月激激激综合网色播免费 | 天海翼一区 在线播放 | 人人草人人干 | 国产成人 免费观看 | 国产在线91区精品 | 91中文字幕在线一区 | 97人人澡 | 精品国产综合成人亚洲区 | 国产成人免费片在线观看 | 5252色欧美在线男人的天堂 | 国产三级不卡 | 看看一级毛片 |