豬兒笨笨的文檔

          主要是個人的一些思考和技術(shù)文章,還有許多翻譯的文檔

           

          Wicket1.3中Class熱加載--使用篇

          Wicket是Apache網(wǎng)站下面的一個頂級項目,是類似于ASP.Net的Web開發(fā)框架,受到很多開發(fā)者的好評。其最新的正式版本是1.3.5,正在開發(fā)的版本是1.4。

          1.3x版本系列是Wicket框架真正走向成熟的標(biāo)志版本,在該版本中提供了Stateless頁面和控件,以及DiskPageStore支持文件存取,以避免大量Stateful控件占用過多內(nèi)存引致OOM,而這一直是Wicket框架被人攻擊的關(guān)鍵點。另外對于開發(fā)人員來說,特別值得一提的則是它在1.3版本中支持了更好的Class熱加載。

          其實J2EE開發(fā)人員都知道在J2EE應(yīng)用程序的開發(fā)中,最麻煩的往往是調(diào)試。雖然JDK已經(jīng)對類的熱加載提供了很好支持,當(dāng)JVM以調(diào)試模式啟動的時候,可以在更改代碼以后,立即看到改動后的效果,但是代碼的修改往往只限于方法的實現(xiàn),如果在類中添加戜刪除了一個Field或者是一個Method(該操作等于修改了類的簽名),那么JDK的熱加載就無法正常生效。雖然大部分的J2EE應(yīng)用服務(wù)器(如Tomcat,WebLogic)都聲稱自己提供了Hot Deploy功能,當(dāng)檢測到類文件被更新以后,可以重新加載相應(yīng)的Web應(yīng)用。但對于大部分的開發(fā)人員來說,這種Hot Deploy功能更象是一個雞肋,看不出什么實際價值。比如說如果在Session中放置了不支持序列化的對象,或者做了動態(tài)類增強(qiáng),那么所謂的Hot Deploy幾乎是百分百出錯。以Tapestry3.04版本為例(它使用了CGLib做類增強(qiáng)),在Tomcat5和WebLogic10環(huán)境上(其它版本應(yīng)該也是相同的,但沒有進(jìn)行過測試),沒有一次能夠正確的Hot Deploy。因此每一次涉及到類簽名的修改,都會重新Deploy應(yīng)用程序(結(jié)果就是經(jīng)常性的OOM),甚至是直接重新啟動應(yīng)用服務(wù)器。即使現(xiàn)在很多開發(fā)人員的硬件已經(jīng)可以算的上高配置,但進(jìn)行上述操作,仍然是一個非常耗時的操作。在我2004年的記憶中,當(dāng)應(yīng)用程序較大時,每天近二分之一的時間在等待服務(wù)器的啟動(或許另外一半時間在等待服務(wù)器的關(guān)閉)。

          雖然Wicket1.2X以前的版本已經(jīng)很好的支持POJO,而且對單元測試提供了很好的支持,但是當(dāng)在應(yīng)用服務(wù)器上運(yùn)行時,仍然避免不了要修改代碼,所以服務(wù)器加載類仍然是一個問題,一件非常痛苦的事情。

          在Wicket1.3中,Wicket小組使用了定制的ClassLoader結(jié)合Web應(yīng)用服務(wù)器的Filter規(guī)范,從而提供新的Class熱加載功能,即使類的簽名有所變更(如Class中添加或移除了新的Field,Method),也能夠正確的加載新類。下面將用一個示例來演示W(wǎng)icket1.3提供的這一新功能。

          為了更好的分析Wicket1.3是如何實現(xiàn)Class熱加載功能,先將Wicket1.3.5的相關(guān)源代碼全部導(dǎo)入Eclipse中,作為一個Web項目,并配置一個Tomcat5作為測試用的Web服務(wù)器,具體的操作步驟就不在這里說明了,有興趣的讀者可以參考我在《Wicket開發(fā)指南》一書的相關(guān)章節(jié),也可以參見這篇文章《導(dǎo)入Wicket項目》,從而在本地建立相應(yīng)的開發(fā)環(huán)境。我這里使用的是Eclipse3.4,但Eclipse3.2和Eclipse3.3都可以,并沒有任何區(qū)別。本機(jī)建立后相應(yīng)環(huán)境的界面如下:



          Wicket項目放置了Wicket的源代碼,用來展示W(wǎng)icket的熱加載功能。而Servers項目是Eclipse中WTP平臺用來定義Web服務(wù)器的配置項目,為了避免Tomcat自動Hot Deploy,需要關(guān)閉該功能。請打開Servers下面子目錄中的Server.xml,并將如下所示的默認(rèn)配置進(jìn)行修改。

          原配置為:

          <Context docBase="Wicket" path="/Wicket" reloadable="true" source="org.eclipse.jst.j2ee.server:Wicket"/>

          修改新配置為:

          <Context docBase="Wicket" path="/Wicket" reloadable="false" source="org.eclipse.jst.j2ee.server:Wicket"/>

          通過將reloadable的屬性改為false,從而關(guān)閉Tomcat的Hot Deploy功能。

          首先看一下Wicket自帶例子中一個簡單的Java類,代碼如下:

          package org.apache.wicket.examples.helloworld;

          import org.apache.wicket.examples.WicketExamplePage;

          import org.apache.wicket.markup.html.basic.Label;

          /**

           * Everybody's favorite example!

           * 

           * @author Jonathan Locke

           */

          public class HelloWorld extends WicketExamplePage

          {

          /**

           * Constructor

           */

          public HelloWorld()

          {

          add(new Label("message""Hello World!"));

          }

          }

          使用WTP自帶的啟動服務(wù)器功能,以Debug模式啟動所配置的Tomcat,然后通過http://127.0.0.1:8080/Wicket/helloworld/來訪問這個人所均知的HelloWorld示例,從而在瀏覽器上看到"Hello World! "的字符串。

          現(xiàn)在來修改一下HelloWorld類的代碼,添加一個方法addControls,將代碼變成:

          package org.apache.wicket.examples.helloworld;

          Import org.apache.wicket.examples.WicketExamplePage;

          import org.apache.wicket.markup.html.basic.Label;

          /**

           * Everybody's favorite example!

           * 

           * @author Jonathan Locke

           */

          public class HelloWorld extends WicketExamplePage

          {

          /**

           * Constructor

           */

          public HelloWorld()

          {

          addControls();

          }

          private void addControls() {

          add(new Label("message""New Hello World!"));

          }

          }

          上述的修改過程中,Eclipse會自動彈出警告框,說代碼簽名已經(jīng)修改,不能熱加載。不必理會這個警告,點擊"Continue"按鈕即可。

          但這一次,瀏覽器絲毫不給面子,仍然是老樣子,頁面上仍然顯示"Hello World",說明新個性的HelloWorld這個類沒有加載成功。

          接下來再嘗試同樣的操作,從而體驗一下Wicket1.3如何支持類的熱加載。在進(jìn)行操作之前,首先通過配置文件打開Wicket的類熱加載功能。修改Wicket項目中web.xml文件,將其中的

          org.apache.wicket.protocol.http.WicketFilter

          全部替換成

          org.apache.wicket.protocol.http.ReloadingWicketFilter

          從而開啟Wicket的類熱加載功能,然后重復(fù)剛才所做的操作,此時奇跡發(fā)生了,雖然我們修改了方法的簽名,但是這一次,在頁面正確的顯示了"New Hello World"字符串。到底Wicket是不是在霍格沃茲魔法學(xué)院學(xué)到什么魔術(shù)了嗎,為我們帶來如此的驚喜呢?后續(xù)文章中將會揭開它的神秘面紗。

          值得要注意的是,雖然Wicket1.3中提供了新的Class熱加載功能,并且該功能在開發(fā)環(huán)境可以正常使用,有效的提高了開發(fā)效率,但是并不建議在上線系統(tǒng)中使用。

          這是因為:

          1. 它并不是一個完善的Class熱加載機(jī)制,因此出錯的機(jī)率仍然比較大,對于上線系統(tǒng),它不夠完善、健壯,開發(fā)人員最好不要依賴于Wicket1.3的類熱加載機(jī)制。

          2. 正式上線的系統(tǒng),其類更新概率是非常小的,而Wicket采用文件掃描的方式檢查類是否被更新,會降低系統(tǒng)性能,在開發(fā)環(huán)境下,這種性能損失并不重要,但對于上線系統(tǒng),可能造成大的性能波動,并嚴(yán)重降低性能表現(xiàn)。


           點擊這里下載Word格式

          posted on 2008-11-22 22:27 豬兒笨笨 閱讀(1984) 評論(2)  編輯  收藏 所屬分類: Java開發(fā)開源軟件Wicket

          評論

          # re: Wicket1.3中Class熱加載功能--使用篇 [未登錄] 2008-11-23 10:51 ivin

          不錯哦。現(xiàn)在每天開發(fā)的時候都得重啟小貓n次,挺煩人的,有時候java文件一個小小的改動都得重啟一下。這樣就不用總start server了
            回復(fù)  更多評論   

          # re: Wicket1.3中Class熱加載--使用篇 [未登錄] 2009-02-11 11:00 li

          這些框架沒有一個好用的,上手都很難,我覺得客戶端html標(biāo)簽里可以采用像flex那樣的collector,renderer,或者自定義一些屬性跟數(shù)據(jù)庫表關(guān)聯(lián),例如
          <select id="" dataTable="" dataColumn="" dataRow="" collector=""
          listRender="">,服務(wù)器端采用一定格式寫一個數(shù)據(jù)庫的文件,比如**.adp,里面的sql文法可以自己定義,當(dāng)客戶端提交表單時,servlet可以攔截并指定用哪個.adp文件,返回的數(shù)據(jù)集結(jié)果就是根據(jù)客戶端的render自動填充,完全不用寫任何一個額外的java文件,web.xml文件也不需要配置,這是最好的方案  回復(fù)  更多評論   

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(18)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 嘉义县| 凤翔县| 大厂| 曲沃县| 伊春市| 类乌齐县| 安福县| 刚察县| 密山市| 河池市| 乌鲁木齐县| 金山区| 邛崃市| 邵东县| 平定县| 城步| 龙口市| 文成县| 东台市| 体育| 综艺| 金阳县| 黑水县| 漯河市| 广饶县| 耿马| 南安市| 镇宁| 蒙城县| 托克逊县| 武胜县| 岳池县| 同心县| 常山县| 平果县| 巧家县| 繁峙县| 达拉特旗| 永兴县| 黄冈市| 蕉岭县|