热部署和类加载器
熱部署
?
對于Java應用程序來說,熱部署就是在運行時更新Java類文件。
?
熱部署的原理是什么
想要知道熱部署的原理,必須要了解java類的加載過程。一個java類文件到虛擬機里的對象,要經過如下過程。
?
首先通過java編譯器,將java文件編譯成class字節碼,類加載器讀取class字節碼,再將類轉化為實例,對實例newInstance就可以生成對象。
類加載器ClassLoader功能,也就是將class字節碼轉換到類的實例。
在java應用中,所有的實例都是由類加載器,加載而來。
一般在系統中,類的加載都是由系統自帶的類加載器完成,而且對于同一個全限定名的java類(如com.csiar.soc.HelloWorld),只能被加載一次,而且無法被卸載。
這個時候問題就來了,如果我們希望將java類卸載,并且替換更新版本的java類,該怎么做呢?
???? 既然在類加載器中,java類只能被加載一次,并且無法卸載。那是不是可以直接把類加載器給換了?答案是可以的,我們可以自定義類加載器,并重寫ClassLoader的findClass方法。想要實現熱部署可以分以下三個步驟:
1、銷毀該自定義ClassLoader
2、更新class類文件
3、創建新的ClassLoader去加載更新后的class類文件。
熱部署與熱加載
Java熱部署與Java熱加載的聯系和區別
Java熱部署與熱加載的聯系
1.不重啟服務器編譯/部署項目
2.基于Java的類加載器實現
?Java熱部署與熱加載的區別
部署方式
熱部署在服務器運行時重新部署項目
熱加載在運行時重新加載class
?實現原理
熱部署直接重新加載整個應用
熱加載在運行時重新加載class
?使用場景
熱部署更多的是在生產環境使用
熱加載則更多的實在開發環境使用
?
V2.class 覆蓋 V1.class文件 會直接被加載嗎?不會呀 重啟后就可以加載新的了! 只會讀取一次
自定義ClassLoader
package com.toov5.test;import java.io.IOException; import java.io.InputStream; /** 穿class文件路徑地址然后 將其讀入jvm中去* */ public class MyClassLoader extends ClassLoader {@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {try {//1獲取文件名稱String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";//2、 文件名稱InputStream iStream =this.getClass().getResourceAsStream(fileName);//3、讀取字節byte[] bytes;bytes = new byte[iStream.available()];iStream.read(bytes); //3、將讀取Byte數組給jvm識別Class對象 return defineClass(name, bytes, 0, bytes.length);} catch (IOException e) {throw new ClassNotFoundException();}}}
自定義一個類:
package com.toov5.test;public class User {public void add(){System.out.println("我是版本1");} }
實現:
package com.toov5.test;import java.lang.reflect.Method;public class Hotswap {public static void main(String[] args) throws InterruptedException, ClassNotFoundException {loadUser();}public static void loadUser() throws ClassNotFoundException{//專門加載類信息MyClassLoader myClassLoader= new MyClassLoader();//使用類加載器讀取信息Class<?> findClass = myClassLoader.findClass("com.toov5.test.User");try {//反射初始化對象Object object = findClass.newInstance();//反射調用方法Method method = findClass.getMethod("add");method.invoke(object);System.out.println(object.getClass());System.out.println(object.getClass().getClassLoader());} catch (Exception e) {}}}
可以設計 每隔多久調用一次這個自自定義的類加載器方法~~~
?
?
關于類加載器
?
?
? Java程序有個類:
? System? ? jvm首先把類的字節碼 加載到內存? ?這個.class放在 classPath下磁盤的某個路徑下? ?這都是類加載器干的
? ?
? ?Java虛擬機中有多個類加載器,系統默認的三個主要的類加載器,每個負責加載特定位置的類:
? ?BootStrap? ?ExtClassLoader? AppClassLoader
? ?
? ?類加載器 也是個Java類,因為其他是Java類的類加載器本身也要被類加載器加載,顯然必須有一個類加載器不是Java類,這個就是BootStrap(是C++的)
? ?Java虛擬機中的所有類加載器采用具有父子關系的樹形結構進行組織,在實例化每個類加載器對象時,需要為其指定一個父級類裝載器對象或者默認采用系統類裝載器為期父類加載。
? ?
public class testClassLoader {public static void main(String[] args) {//得到這個類的類加載器的類的名字 類加載器屬于一個類String name = testClassLoader.class.getClassLoader().getClass().getName();System.out.println(name);} }
結果:
?
看下System:
public class testClassLoader {public static void main(String[] args) {//得到這個類的類加載器的類的名字 類加載器屬于一個類String name1 = System.class.getClassLoader().getClass().getName();System.out.println(name1);} }
?空指針異常了
?特殊的類加載器 不是Java類??
?只要是Class對象一定是由類加載器加載出來的 不可能不存在
?這個可能性是在跟前面?
System.class.getClassLoader()
沒有這個對象
是因為特殊類加載器? C++寫的那個。用Java程序去獲得這個名字就是 Null了
?
循環打印下:
public class testClassLoader {public static void main(String[] args) {ClassLoader classLoader = testClassLoader.class.getClassLoader();while ( classLoader != null){System.out.println(classLoader.getClass().getName());classLoader = classLoader.getParent();}System.out.println(classLoader);} }
?
?如果有兩份,那么加載父類包下面的哦!
?
?
要想自己寫類加載器,需要掛到爸爸下面。
?
?當Java虛擬機要加載一個類時候,到底派哪個類加載器去加載?
? ? 首先當前線程的類加載器去加載線程中的第一個類
? ? 如果類A中引用了類B, Java虛擬機將使用加載類A的類加載器來加載類B
? ? 還可以直接調用ClassLoader.loadClass() 方法來指定某個類加載器去加載某個類
?
? ?每個類加載器加載類時候,現委托給上級類加載器
? ? ? ?當所有祖宗類的加載器沒有加載到類,回到發起者類加載器,還加載不了,則拋出ClassNotFoundException,不是再去找發起者類加載器的兒子,因為沒有getChild方法,即便是有,如果多個兒子,找哪個呢?
? ??
?每個ClassLoader本身只能分別加載特定位置和目錄中的類,但他們可以委托其他的類加載器去加載類,這就是類加載器的委托機制。類加載器一級一級委托到BootStrap類加載器,當BootStrap無法加載當前所需要加載的類時候,然后才一級一級回退到子孫類加載器進行真正的加載。當退回到最初的類加載器時候,如果它自己也不能完成類的加載,那就應報告ClassNotFountException異常
?
?自定義類加載器:
?
?待續
??
?
轉載于:https://www.cnblogs.com/toov5/p/9878959.html
總結
- 上一篇: 文本换行
- 下一篇: 棉怕八月连天阴的下一句是什么呢?