隨筆 - 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 閱讀(360) 評論(1)  編輯  收藏 所屬分類: Tomcat源代碼

          評論

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

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

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


          網站導航:
           
          主站蜘蛛池模板: 扬中市| 孟州市| 双峰县| 杭锦后旗| 重庆市| 博白县| 汪清县| 雷山县| 通江县| 凉城县| 靖宇县| 吉水县| 郁南县| 平南县| 镇原县| 且末县| 保德县| 阿坝| 车致| 榆林市| 吴堡县| 新密市| 靖宇县| 洛川县| 车致| 宁夏| 马公市| 樟树市| 平凉市| 绥滨县| 天等县| 鄯善县| 海盐县| 筠连县| 天台县| 武平县| 万盛区| 江油市| 民勤县| 江达县| 横山县|