熱部署原理解析

一、Java類加載過程


把Java文件編譯成字節碼文件,再把字節碼文件序列化成相應的串,再把序列化後的串編譯成源碼對象,再把源碼對象編譯成.class文件,classload加載器加載class類到Java虛擬機中。

類加載的5個階段:


加載階段

找到類的靜態存儲結構,並加載到虛擬機裏面,然後轉換成方法區的運行時數據結構,生成class對象,加載階段,用戶可以自定義類加載器參與進來。

驗證階段

主要確保字節碼安全的,確保不會對虛擬機安全造成危害,通過JVM啓動參數來禁用一些驗證,但不推薦修改設置,參數禁用會對虛擬機安全可能造成一些危害。

準備階段

確定內存佈局,初始化內存變量,注意點:賦初始值,不會執行程序自己定義的賦值操作,比如定義了一個私有變量:private static int count = 12,在準備階段並不是把count初始爲了12,這裏是會賦初始值,int初始值爲0,所以會把這私有靜態變量賦值爲0,而不是12。

解析階段

這個階段主要是將符號引用變爲直接引用。

初始化階段

調用程序自定義的代碼。比如private static int count = 12, count在本階段將會被初始化爲12,而不是之前準備階段的0,初始化階段會生成clean int 方法,這個方法由編譯器自動收集類中的所有類變量的賦值、動作和靜態語句塊中的語句合併,同一個類加載器中,只會將一個類型初始化一次,Java虛擬機沒有強制約束什麼時候開始初始化階段,但規定了5種情況必須立即初始化,當然這之前的幾種操作都是已經運行了的。5種情況如下:

1. 遇到new、 get static 、post static、 invoke static這四條字節碼指令的時候,如果類沒有初始化,需要觸發初始化,注意的是final修飾的類,會在編譯期的時候,將結果放在常量池,即使調用也不會觸發初始化,因爲final修飾的是常量,會把常量放在常量池,調用常量不會觸發初始化這個階段。

2. 使用java.long.reflect包裏方法,即對類進行反射調用的時候,如果類沒初始化的話,需要初始化。

3. 當初始化一個子類的時候,如果父類還沒有初始化,需要先初始化父類,再初始化子類

4. 虛擬機啓動的時候,用戶制定一個要執行的主類,虛擬機會先初始化這個主類,例子:我們寫的java程序,在某一個類裏面寫了一個main方法,通過運行這個main方法啓動這個程序,虛擬機會先初始化這個main方法所在的類。

5. 使用jdk1.7動態語言支持的時候,如果java.lang.invoke.methondhandler類實例解析的最後結果是ref_getstatic、ref_putstatic、ref_invokestatic方法句柄的時候,如果句柄對應的類沒有初始化,那就需要先初始化句柄對應的類。

二、Java類加載器的特點

1. 由AppClass Loader(系統類加載器)開始加載指定的類;

2. 類加載器將加載任務交給其父,如果其父找不到,再交給自己去加載;

3. Bootstrap Loader (啓動類加載器)是最頂級的類加載器。

三、Java類熱部署實現方式

1. 類的熱加載實現熱部署


這個方式主要通過繼承java.lang.classloader這個類,複寫findClass方法,這個方法目標是爲自定義加載器容納所有的代碼,不需要重複寫其他的代碼,例如加載失敗時,調用系統的classloader是不需要的。classLoader需要從源文件中獲取字節碼,一旦找到字節碼會調用defineClass方法,classLoader實例調用此方法也是非常重要的,因此,如果兩個class實例定義來自不同和相同文件的字節碼,則被定義的類也被區別對待,因爲一個類加載器只能初始化一次。

2. 配置Tomcat實現熱部署

1.直接把項目web文件夾放在webapps裏面。

2. 在tomcat/conf/server.xml文件裏面的<host></host>內部添加<context/>標籤,有這個context標籤的一些屬性經過一些配置實現熱部署。

3. 在%tomcat_home%\conf\Catalina\localhost裏面添加一個xml文件,注意的是,訪問的時候以localhost中添加的一個xml的名字作爲路徑一部分來訪問的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章