Java 熱更新 加載class和jar

1、首先了解下java幾個加載器的基本原理:

         Java 中的類加載器大致可以分成兩類,一類是系統提供的,另外一類則是由 Java 應用開發人員編寫的。系統提供的類加載器主要有下面三個: 
     引導類加載器(bootstrap class loader):它用來加載 Java 的核心庫,是用原生代碼來實現的,並不繼承自 java.lang.ClassLoader。 
     擴展類加載器(extensions class loader):它用來加載 Java 的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄裏面查找並加載 Java 類。 
     系統類加載器(system class loader):它根據 Java 應用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應用的類都是由它來完成加載的。可以通過 ClassLoader.getSystemClassLoader() 來獲取它。

     除了系統提供的類加載器以外,開發人員可以通過繼承 java.lang.ClassLoader 類的方式實現自己的類加載器,以滿足一些特殊的需求。 

      我們平時程序執行的時候在類加載器中尋找類的結構的順序是:引導類加載器-》 擴展類加載器-》系統類加載器-》我們自定義的一些類加載器,每個類加載器都有自己的空間,同一個加載器裏面的類的二進制名字必須是唯一的,當然同一個類也可以存在不同的加載器內存區域裏面,不過我們尋找類的時候是按順序找的,一但找的也就不會繼續往下找了,最終也沒找到就會報類不存在異常。 
    我們如果想動態加載類的話就要仿照我們用的服務器如tomcat和weblogic之類的,他們的開發模式也就是把所有的類都加載到自身的類加載器中,當文件被替換的時候他們就重新加載新的class到內存裏面去,從而實現了類的動態加載。

2、使用概要:

  File   file   =   new   File(jar文件全路徑);   
  URL   url   =   file.toURI().toURL(); 
  URLClassLoader   loader   =   new   URLClassLoader(new   URL[]   {   url   });   
  Class   tidyClazz   =   loader.loadClass(所需class的含包名的全名);  

詳細說明:

我們知道,Java利用ClassLoader將類載入內存,並且在同一應用中,可以有很多個ClassLoader,通過委派機制,把裝載的任務傳遞給上級的裝載器的,依次類推,直到啓動類裝載器(沒有上級類裝載器)。如果啓動類裝載器能夠裝載這個類,那麼它會首先裝載。如果不能,則往下傳遞。當父類爲null時,JVM內置的類(稱爲:bootstrap class loader)就會充當父類。想想眼下的越來越多用XML文件做配置文件或者是描述符、部署符。其實這些通過XML文檔描述的配置信息最終都要變成Java類,實都是通過ClassLoader來完成的。URLClassLoader是ClassLoader的子類,它用於從指向 JAR 文件和目錄的 URL 的搜索路徑加載類和資源。也就是說,通過URLClassLoader就可以加載指定jar中的class到內存中。

參考代碼:

public class ReloadClassLoader extends ClassLoader{
/**

* @param classFile class文件
* @return
* @throws Exception
*/
public Class<?> loadClass(File classFile){
// 一般的class文件通常都小於100k,如果現實情況超出這個範圍可以放大長度
byte bytes[] = new byte[(int) classFile.length()];
FileInputStream fis = null;
Class<?> clazz = null;
try
{
fis = new FileInputStream(classFile);
int j = 0;
while (true)
{
int i = fis.read(bytes);
if (i == -1)
break;
j += i;
}
clazz = super.defineClass(null, bytes, 0, j);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return clazz;
}
/**

* @param JarFile Jar包
* @param className 全類名
* @return 
* @throws Exception
*/
public Class<?> loadJAR(File JarFile,String className){
Class<?> cls = null;
         if (!JarFile.exists()) {
             return null;
         }
        
try {
URL url = JarFile.toURI().toURL();
URLClassLoader classLoader = new URLClassLoader(new URL[] { url }, Thread.currentThread().getContextClassLoader());
cls = classLoader.loadClass(className);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
         return cls;
}
}





發佈了16 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章