自己最近在學習Java Web編程,先是讀了Sun公司的官方文檔Java EE 5的tutorial(http://java.sun.com/javaee/5/docs/tutorial/doc/)中的關鍵章節,然后學了一陣Java Passion里的相關在線課程(見:http://www.javapassion.com/j2ee/),前幾天還看完了一本電子書<<Struts2 in Action>>,但總覺得缺少了什么。這兩天突然想起為什么不把tomcat的源碼下載下來仔細研究研究呢?記得以前自己一直想學習著名的Java Build工具Ant(http://ant.apache.org/)的用法,但怎么看文檔都理解不深,試了幾次效果都不好。最后終于把源碼下載下來讀了其中的主要源碼,頓時感覺不僅輕松學會了Ant的用法,而且知道為什么要那么設計。這給我很大的啟發:對于開源軟件來說,比書籍更好的是在線文檔,比在線文檔更好的源碼本身。其實tomcat和Ant有很深的內在聯系,tomcat的早期開發者James Duncan Davidson就是Ant工具的發明人,為了解決開發tomcat過程中各種復雜的build流程他專門創造了Ant。顯然,了解Ant對讀懂tomcat會有極大的幫助。tomcat現在的架構師Craig McClanahan又是另一個著名的MVC框架struts的發明人。

          步入正題吧。

          首先到tomcat.apache.org里下載最新的源碼包,現在最新的版本是6.0.20,下載后解壓縮,發現它的根目錄里有一個build.xml,這是Ant的默認輸入文件。tomcat源碼本身是用Eclipse寫的,所以我們要做的第一步是在Eclipse里把tomcat工程部署好,這其實很容易,在Eclipse里選擇File>New>Project,選擇Java project with an existing Ant buildfile,選擇那個build.xml就可以了。
          然后是下載tomcat的依賴包,這一步也很容易,只要執行ant download(可以打開Eclipse的Ant的view以方便操作)就可以了。它會把下載的依賴包放在一個名稱為base.path的目錄,最好自己配置一下,它默認配置在build.xml.properties.default文件里。下載完依賴包后再ant deploy后就在output/build目錄里得到了可以使用的tomcat。Ant真方便!
          Eclipse里要想使得即時編譯沒有任何錯誤提示,需要在build path里配置兩個變量:一個是ANT_HOME,另一個是保存依賴包的TOMCAT_LIBS_BASE,就是保存依賴包的那個目錄。
          看一下tomcat的目錄結構,真的很簡單,啟動tomcat的腳本放在bin目錄里,分別有對應windows和unix的兩種腳本。我在Ubuntu環境下,所以先來看一下它的unix腳本。啟動腳本是startup.sh,它實際上是另一個腳本catalina.sh的封裝,所以直接跳到catalina.sh,它會調用另一個腳本setclasspath.sh以設置java,catalina.sh設置好各種環境后會調用tomcat的啟動類:org.apache.catalina.startup.Bootstrap的start方法。
          跟蹤一下代碼,Bootstrap類里主要是設置幾個不同的ClassLoader和JMX Server,然后通過反射技術把任務移交給真正的啟動類:org.apache.catalina.startup.Catalina。
          怎么樣,這是不是很像啟動腳本一樣,先有個包裝,最后都調的是catalina,不管是shell還是Java的類。
          Catalina里的方法最主要是這個方法:protected Digester createStartDigester();它是讀取conf/server.xml配置文件進行動態加載配置組件的過程,用的是apache的另一個子項目:Digester,它也是struts讀取配置文件動態加載的機制,別忘了tomcat的架構師可是struts項目的作者啊。
          加載完server的層次化組件后,通過調用 ((Lifecycle) server).start();整個server就自頂向下啟動起來了。另外,代碼中大量運用了observer這個設計模式,把各種狀態的變化通知給相應的listener。
          在Bootstrap類的源碼中發現一處小的bug:

          if (replace && log.isDebugEnabled())
          log.debug("Expanded " + before + " to " + replace);

          應該是:
          if (replace && log.isDebugEnabled())
          log.debug("Expanded " + before + " to " + repository);
          posted on 2011-01-20 17:53 hello 閱讀(3783) 評論(0)  編輯  收藏 所屬分類: tomcat
          主站蜘蛛池模板: 延边| 龙州县| 四子王旗| 乐昌市| 徐州市| 周口市| 长兴县| 渝中区| 皋兰县| 乌拉特后旗| 万荣县| 苏州市| 通河县| 商城县| 石门县| 南乐县| 夏津县| 朝阳县| 车致| 丹巴县| 香格里拉县| 望都县| 梓潼县| 鱼台县| 凤山市| 米易县| 应用必备| 兴海县| 大洼县| 雅江县| 阿合奇县| 曲麻莱县| 沈阳市| 云浮市| 贵德县| 南投市| 霍林郭勒市| 霞浦县| 泰和县| 乾安县| 黑山县|