Java類中熱替換 – JAVA編程語言程序開發技術文章

類的熱替換是Java在線升級系統設計中的基礎技術,從文中給出的實例來看,構建在線升級系統不僅僅是一個技術問題,還牽扯到很多管理方面的因素,比如:如何管理、部署系統中的可在線升級部分和不可在線升級部分以降低系統的管理、維護成本等。


對於許多關鍵性業務或者龐大的Java系統來說,如果必須暫停系統服務才能進行系統升級,既會大大影響到系統的可用性,同時也增加瞭系統的管理和維護成本。因此,如果能夠方便地在不停止系統業務的情況下進行系統升級,則可以很好地解決上述問題。


JavaClassLoader技術剖析


要構建在線升級系統,一個重要的技術就是能夠實現Java類的熱替換——也就是在不停止正在運行的系統的情況下進行類(對象)的升級替換。而Java的ClassLoader正是實現這項技術的基礎。


在Java中,類的實例化流程分為兩個部分:類的加載和類的實例化。類的加載又分為顯式加載和隱式加載。大傢使用new關鍵字創建類實例時,其實就隱式地包含瞭類的加載過程。對於類的顯式加載來說,比較常用的是Class.forName。其實,它們都是通過調用ClassLoader類的loadClass方法來完成類的實際加載工作的。直接調用ClassLoader的loadClass方法是另外一種不常用的顯式加載類的技術。


                                          Java類中熱替換(轉載) - 七月桃花 - 七月桃花


                                        圖1.Java類加載器層次結構圖


ClassLoader在加載類時有一定的層次關系和規則。在Java中,有四種類型的類加載器,分別為:BootStrapClassLoader、ExtClassLoader、AppClassLoader以及用戶自定義的ClassLoader。這四種類加載器分別負責不同路徑的類的加載,並形成瞭一個類加載的層次結構。


BootStrapClassLoader處於類加載器層次結構的最高層,負責sun.boot.class.path路徑下類的加載,默認為jre/lib目錄下的核心API或-Xbootclasspath選項指定的jar包。ExtClassLoader的加載路徑為java.ext.dirs,默認為jre/lib/ext目錄或者-Djava.ext.dirs指定目錄下的jar包加載。AppClassLoader的加載路徑為java.class.path,默認為環境變量CLASSPATH中設定的值。也可以通過-classpath選型進行指定。用戶自定義ClassLoader可以根據用戶的需要定制自己的類加載過程,在運行期進行指定類的動態實時加載。


這四種類加載器的層次關系圖如圖1所示。一般來說,這四種類加載器會形成一種父子關系,高層為低層的父加載器。在進行類加載時,首先會自底向上挨個檢查是否已經加載瞭指定類,如果已經加載則直接返回該類的引用。如果到最高層也沒有加載過指定類,那麼會自頂向下挨個嘗試加載,直到用戶自定義類加載器,如果還不能成功,就會拋出異常。Java類的加載過程如圖2所示。


 


                         Java類中熱替換(轉載) - 七月桃花 - 七月桃花


                                                              圖2.Java類的加過程


每個類加載器有自己的名字空間,對於同一個類加載器實例來說,名字相同的類隻能存在一個,並且僅加載一次。不管該類有沒有變化,下次再需要加載時,它隻是從自己的緩存中直接返回已經加載過的類引用。


我們編寫的應用類默認情況下都是通過AppClassLoader進行加載的。當我們使用new關鍵字或者Class.forName來加載類時,所要加載的類都是由調用new或者Class.forName的類的類加載器(也是AppClassLoader)進行加載的。要想實現Java類的熱替換,首先必須要實現系統中同名類的不同版本實例的共存,通過上面的介紹我們知道,要想實現同一個類的不同版本的共存,我們必須要通過不同的類加載器來加載該類的不同版本。另外,為瞭能夠繞過Java類的既定加載過程,我們需要實現自己的類加載器,並在其中對類的加載過程進行完全的控制和管理


<P style="PADDING-BOTTOM: 0px; LINE-HEIGHT: 22px; MARGIN: 0px 0px 10px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP

發佈留言