更新時間:2022-07-07 12:12:33 來源:動力節點 瀏覽3275次
動力節點小編來為大家介紹Java熱部署的原理。
對于Java應用來說,熱部署就是在運行時更新Java類文件。
您可以在不重新啟動應用程序的情況下更新應用程序。比如電腦不用重啟就可以更換U盤。
OSGI 也因其模塊化和熱部署而廣受歡迎。
要知道熱部署的原理,就必須了解java類的加載過程。一個java類文件到虛擬機中的一個對象必須經過以下過程。
通過java編譯器,將java文件編譯成類字節碼,類加載器讀取類字節碼,然后將類轉化為實例,可以為實例newInstance生成一個對象。
ClassLoader 的作用是將類字節碼轉換為類的實例。
在 Java 應用程序中,所有實例都由類加載器加載。
一般在系統中,類的加載是由系統自帶的類加載器完成的,對于同名的java類(如com.csiar.soc.HelloWorld),只能加載一次并且無法加載。卸載。
這時,問題來了。如果我們要卸載java類并替換較新版本的java類,我們應該怎么做呢?
由于在類加載器中,java類只能加載一次,不能卸載。是否可以直接更改類加載器?答案是肯定的,我們可以自定義類加載器,重寫ClassLoader的findClass方法。實現熱部署可以分為以下三個步驟:
(1)銷毀自定義的ClassLoader
(2)更新類文件
(3)新建一個ClassLoader來加載更新的類文件。
示例代碼如下:
package com.csair.soc.hotswap;
import java.io.IOException;
import java.io.InputStream;
/**
* Custom class loader, and override the findClass method
*/
public class MyClassLoader extends ClassLoader{
@Override
public Class<?> findClass(String name) throws ClassNotFoundException{
try{
String fileName = name.substring(name.lastIndexOf("." )+1) + ".class";
InputStream is = this.getClass().getResourceAsStream(fileName);
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b. length);
} catch(IOException e){
throw new ClassNotFoundException(name);
}
}
}
需要更新的類文件:
package com.csair.soc.hotswap;
public class HelloWorld {
public void say(){
System. out.println( "Hello World V1");
}
}
在項目根目錄下,生成V2版本的HelloWorld.class,內容如下。
package com.csair.soc.hotswap;
public class HelloWorld {
public void say(){
System. out.println( "Hello World V2");
}
}
測試主程序
package com.csair.soc.hotswap;
import java.io.File;
import java.lang.reflect.Method;
public class Hotswap {
public static void main(String[] args) throws Exception {
loadHelloWorld();
//Recycle resources and release the HelloWorld.class file so that it can be replaced
System. gc();
Thread. sleep(1000);//Waiting for resources to be recycled
File fileV2 = new File( "HelloWorld.class");
File fileV1 = new File(
"bin\\com\\csair\\soc\\hotswap\\HelloWorld.class" );
fileV1.delete();//Delete the V1 version
fileV2.renameTo(fileV1);//Update V2 version
System. out.println( "Update success!");
loadHelloWorld();
}
public static void loadHelloWorld() throws Exception {
MyClassLoader myLoader = new MyClassLoader();//Custom class loader
Class<?> class1 = myLoader
.findClass( "com.csair.soc.hotswap.HelloWorld");//Class instance
Object obj1 = class1.newInstance();//Generate a new object
Method method = class1.getMethod( "say");
method.invoke(obj1);//Execute method say
System. out.println(obj1.getClass());//Object
System. out.println(obj1.getClass().getClassLoader());//Object class loader
}
}
輸出結果:
你好世界V1
com.csair.soc.hotswap.HelloWorld 類
com.csair.soc.hotswap.MyClassLoader@bfc8e0
更新成功!
你好世界V2
com.csair.soc.hotswap.HelloWorld 類
com.csair.soc.hotswap.MyClassLoader@860d49
根據結果??,我們可以看到 HelloWorld 類更新成功,無需重新啟動應用程序。如果大家想了解更多相關知識,可以關注一下動力節點的Java在線學習,里面的課程內容從入門到精通,細致全面,很適合0基礎的小伙伴學習,希望對大家能夠有所幫助。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習