永遠年輕,永遠熱淚盈眶。
當系統有點小bug或者有點小需求而項目特別大或者無法重啓時是個很麻煩的事情,爲了解決這些問題,熱更新應運而生了。
熱更新,即classloader加載class文件。java運行的時候分別用不同的classloader加載jre/lib/*,jre/lib/ext,classpath
對於classloader ,java自帶三個即Bootstrap ClassLoader,Extention ClassLoader, Appclass Loader分別加載上述的三個文件,
Bootstrap ClassLoader : java最頂層的classloader,用c/c++實現,-Xbootclasspath可用於追加路徑,該classloader是最頂層的classloader,java虛擬機運行的時候加載jre/lib/*.jar ,(System.getProperty("sun.boot.class.path")結果中的包)
Extention ClassLoader : 擴展類加載器,加載jre/lib/ext/*.jar,-D java.ext.dirs可以選指定目錄。System.getProperty("java.ext.dirs")獲取具體目錄;
Appclass Loader: 加載當前classpath中的類,System.getProperty("java.class.path"); 獲取目錄。
簡單的小demo:
public class App
{
public static void main( String[] args ) throws Exception
{
while (true) {
URL url = new URL("file:/E:/java/test/bin/test");
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url},urlClassLoaderP);
Class<?> loadClass = urlClassLoader.loadClass("test.BitTest");
Object newInstance = loadClass.newInstance();
Method method = loadClass.getMethod("sayHello",String.class);
method.invoke(newInstance,"sssss");
Thread.sleep(5000L);
urlClassLoader.close();
}
}
}
每隔5秒加載類文件,文件目錄爲file:/E:/java/test/bin/
雙親委託:
一個類的加載首先問父類加載器,父類加載器然後才輪到子類加載,比如下面
public static void main( String[] args ) throws Exception
{
URL urlparnt = new URL("file:/E:/java/test/bin/test");
URLClassLoader urlClassLoaderP = new URLClassLoader(new URL[]{urlparnt});
while (true) {
URL url = new URL("file:/E:/java/test/bin/");
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url},urlClassLoaderP);
Class<?> loadClass = urlClassLoader.loadClass("test.BitTest");
Object newInstance = loadClass.newInstance();
Method method = loadClass.getMethod("sayHello",String.class);
method.invoke(newInstance,"sssss");
Thread.sleep(5000L);
urlClassLoader.close();
}
}
url可以指定父類加載器,如果父類能加載 就直接用父類加載 ,子類不在重新加載,也就是不會重複加載class,當父類無法加載的時候,子類纔會加載
第一次寫blog,格式不是很好,希望堅持,qq1071893377 一起交流