隨筆 - 8, 文章 - 0, 評論 - 6, 引用 - 0
          數據加載中……

          Tomcat筆記(三)

          來看看ContainerBasestart方法:
           1public synchronized void start() throws LifecycleException {
           2
           3        //如果Container已經處于start狀態,直接返回
           4        if (started) {
           5            if(log.isInfoEnabled())
           6                log.info(sm.getString("containerBase.alreadyStarted", logName()));
           7            return;
           8        }

           9        
          10        // Notify our interested LifecycleListeners
          11        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
          12
          13        started = true;
          14
          15        // Start our subordinate components, if any
          16        if ((loader != null&& (loader instanceof Lifecycle))
          17            ((Lifecycle) loader).start();
          18        logger = null;
          19        getLogger();
          20        if ((logger != null&& (logger instanceof Lifecycle))
          21            ((Lifecycle) logger).start();
          22    //用來管理session
          23        if ((manager != null&& (manager instanceof Lifecycle))
          24            ((Lifecycle) manager).start();
          25    //看名字就知道是干什么的,不過研究集群的優先級很低
          26        if ((cluster != null&& (cluster instanceof Lifecycle))
          27            ((Lifecycle) cluster).start();
          28    //用來進行訪問控制,或者權限控制的
          29        if ((realm != null&& (realm instanceof Lifecycle))
          30            ((Lifecycle) realm).start();
          31    //和JNDI相關
          32        if ((resources != null&& (resources instanceof Lifecycle))
          33            ((Lifecycle) resources).start();
          34
          35        //啟動所有子container
          36        Container children[] = findChildren();
          37        for (int i = 0; i < children.length; i++{
          38            if (children[i] instanceof Lifecycle)
          39                ((Lifecycle) children[i]).start();
          40        }

          41
          42        // 啟動Container內部持有的pipeline對象,Container對Pipeline接口的實現就是通過調用這個內部持有的Pipeline對象
          43        if (pipeline instanceof Lifecycle)
          44            ((Lifecycle) pipeline).start();
          45
          46        // Notify our interested LifecycleListeners
          47        lifecycle.fireLifecycleEvent(START_EVENT, null);
          48
          49        // 注釋說這個函數用來check session是否過期,但看的不是太懂
          50        threadStart();
          51
          52        // Notify our interested LifecycleListeners
          53        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
          54
          55}

          56
           

          所有和clusterrealm相關都放在最后來研究了,不管怎么樣先把tomcat如何處理request的整個過程串起來對現在的我來說是最重要的。另外還有Tomcat中的很多部件都用到了JMX API,即SNMPJava實現來進行性能檢測和管理,這個也會放在最后研究。

          ContainerBase就看這么多了,下面來看看StandardEngine這個類。除去和clusterrealmJMX相關的方法后,StanderdEngine剩下的方法就很很少了。

          StandardEngine有一個Service類型的成員。Java doc中指出Service就是由很多共享同一個ContainerConnector組成。一個Service對應于一個Container,來自這個Service的任何一個Connectorrequest都會由其對應的Container進行處理。看到現在的感覺就是ConnectorContainer提供request對象,并接受Container返回的response對象。在Tomcat中有很多類別都被用來體現現request或者response,例如org.apache.catalina.connector .Request就是Coyote request的一個wrapper類,Coyote這個framework幫助封裝了底層的網絡復雜性,向上提供一個統一的接口。我想tomcat既能夠成為一個standalonehttpjsp/Servlet服務器,也能夠同apache http server集成,很可能就是依賴于Coyote提供的統一接口。

          在構造函數中會將StandardEngine這個Pipeline的最后一個Valve,即Basic設置為StandardEngineValve。來看看StandardEnginValueinvoke方法
           1public final void invoke(Request request, Response response)
           2        throws IOException, ServletException {
           3
           4        // Select the Host to be used for this Request
           5        Host host = request.getHost();
           6        if (host == null{
           7            response.sendError
           8                (HttpServletResponse.SC_BAD_REQUEST,
           9                 sm.getString("standardEngine.noHost"
          10                              request.getServerName()));
          11            return;
          12        }

          13
          14        // Ask this Host to process this request
          15        host.getPipeline().getFirst().invoke(request, response);
          16
          17    }

          18
           

          可以看出在處理到StandardEngine這個Pipeline的最后一個Valve時,會根據當前request所指定的Host,將當前的requestresponse傳遞給該Host這個Pipeline的第一個Valve進行處理。

          我想Tomcat中的EngineHostContextWrapper處理request生成response的過程大概是這樣的:

          Engine在收到request后在其Pipeline中的每一個Valverequest進行處理,也可能會生成response的某些部分,在最后一個Valve中將requestresponse傳給下一級ContainerHost的第一個ValveHost重復同樣過程,繼續傳遞給ContextContext再傳遞給Wrapper。由于Wrapper代表的是Servlet對象,因此在Wrapper處所有的處理都結束了,response對象生成完畢。當然了,如果在某一級中無法找到request要求的下一級對象,則整個處理過程也會立即結束。

          posted on 2007-05-30 22:58 Job Hu 閱讀(361) 評論(1)  編輯  收藏 所屬分類: Tomcat源代碼

          評論

          # re: Tomcat筆記(三)  回復  更多評論   

          Cool~寫的好!
          莫非你也要寫一個類似tomcat的咚咚?
          2007-06-05 10:26 | yans

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 民丰县| 武城县| 游戏| 筠连县| 微山县| 枞阳县| 六枝特区| 京山县| 山东| 神池县| 海宁市| 蕲春县| 防城港市| 佛山市| 澄迈县| 铜川市| 麻栗坡县| 徐汇区| 阳原县| 洞口县| 武冈市| 鸡西市| 阿拉善左旗| 靖宇县| 乌恰县| 新乡市| 长治市| 甘泉县| 绍兴县| 温泉县| 石城县| 北碚区| 新泰市| 碌曲县| 鄂托克前旗| 南召县| 通海县| 陕西省| 丹东市| 五台县| 台安县|