日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

How Tomcat Works(五)

系統(tǒng) 2778 0

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

  • 實(shí)現(xiàn)org.apache.catalina.Connector接口

  • 負(fù)責(zé)創(chuàng)建實(shí)現(xiàn)org.apache.catalina.Request接口的Request對(duì)象

  • 負(fù)責(zé)創(chuàng)建實(shí)現(xiàn)org.apache.catalina.Response接口的Response對(duì)象

org.apache.catalina.Connector接口最重要的方法是getContainer() 、setContainer()、creatRequest()、 creatResponse(),setContainer()方法用于設(shè)置相關(guān)聯(lián)的servlet容器,getContainer()方法獲取相關(guān)連的servlet容器,creatRequest()方法為http請(qǐng)求創(chuàng)建request對(duì)象,creatResponse()方法創(chuàng)建response對(duì)象

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

在HttpConnector對(duì)象的初始化方法initialize()里面,調(diào)用私有方法open(),創(chuàng)建ServerSocket實(shí)例

      
        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()顯然是創(chuàng)建ServerSocket實(shí)例的工廠,方法如下

      
        /**
      
      
        
     * 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實(shí)現(xiàn)了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);
        }

    }
      
    

首先是啟動(dòng)HttpConnector連接器線程,然后是初始化最少數(shù)量的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連接器實(shí)現(xiàn)了java.lang.Runnable接口,我們分析它的run()方法實(shí)現(xiàn)

      
        /**
      
      
        
     * 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();
        }

    }
      
    

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

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

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

這里是創(chuàng)建最少數(shù)量的HttpProcessor處理器并入棧,我們先分析newProcessor()方法的實(shí)現(xiàn)

      
        /**
      
      
        
     * 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);

    }
      
    

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

      
        /**
      
      
        
     * 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對(duì)象入棧,成員變量Stack processors = new Stack()繼承自 Vector ,是一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)

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

      
        /**
      
      
        
     * 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對(duì)象 ,后面的代碼不用多加解釋了吧,你懂的!

后面那段代碼是干嘛的

      
        //
      
      
         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處理器類的源碼分析相對(duì)獨(dú)立,加上篇幅還比較多,因此本文先到這里,下文繼續(xù)……

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

本系列How Tomcat Works系本人原創(chuàng)?

轉(zhuǎn)載請(qǐng)注明出處 博客園 刺猬的溫馴?

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

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

How Tomcat Works(五)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 堆龙德庆县| 河津市| 察哈| 梅河口市| 乃东县| 台南市| 囊谦县| 宁陕县| 通渭县| 昌都县| 疏勒县| 吴川市| 黑山县| 灵武市| 永川市| 长泰县| 游戏| 嘉禾县| 定州市| 贵州省| 兴隆县| 泗阳县| 中山市| 林芝县| 财经| 长海县| 吉水县| 闵行区| 湘阴县| 乐业县| 谷城县| 老河口市| 博爱县| 衡阳市| 盱眙县| 黄骅市| 安仁县| 上虞市| 宜兰市| 玉山县| 田阳县|