請教:應用伺服器如何識別被更新的class檔案,是透過ClassLoader嗎?

諸葛發表於2006-07-26
我拿Tomcat5.0.28做的試驗
public class Test{
static int a = 99;
static{
a = 5662;
System.out.println("類初始化");
}

public Test(){
System.out.println("建立了一個TTTTT的例項");
}
public static void stm(){
System.out.println("--------static-------!"+a);
}
public void m(){
System.out.println("--------nonstatic-------!"+a);
}
protected void finalize() throws Throwable {
super.finalize();
System.out.println("--------物件被釋放---------!");
}
}

將建立一個Test類的物件,放到session中,
會列印出:
類初始化
建立了一個TTTTT的例項

然後執行m方法,列印出("--------nonstatic-------!5662
然後修改Test類,將m方法改為:
public void m(){
System.out.println("----modified----nonstatic-------!"+a);
}
再次執行,列印出的就就是新的方法中的內容:----modified----nonstatic-------!5662

但是沒有列印出“類初始化”,也就是說沒有執行static初始塊。
同樣的試驗,發現static的方法也是被更新後的。
同時,我也嘗試列印出Test.class.hashcode();,發現這個值一直沒有變,這個方法是來自Object,Class類並沒有override它,還有一些發現,我總結了一下tomcat的特點:
*Tomcat會識別應用目錄下Class檔案的更新操作,並透過某種機制將新的位元組碼替代舊的位元組碼
*Tomcat不會重新載入一個類,因為static塊沒有被執行
*Tomcat動態更新不允許增加方法、減少方法、增加/減少欄位等操作。這些操作都會引起Tomcat崩潰。

至於Tomcat對servlet的更新相對就簡單一些了,畢竟servlet實現了介面,而且都是完全由容器管理的,建立、更新、再次載入在理論上也都不是什麼難事。可是對於Test這種完全自定義的類,實現動態更新讓我困擾不已。小弟嘗試從ClassLoader的角度分析這個問題,但是最後發現那樣是沒有辦法達到這種效果的。小弟也嘗試從Class類入手,現在還沒有結果,請問哪位大蝦能給小弟指點迷津,小弟不勝感激!

相關文章