URLClassLoader使用方法和例項 類載入器
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到記憶體中。
下面來看一個例子,在該例子中,我們要完成的工作是利用URLClassLoader載入jar並執行其中的類的某個方法。
首先我們定義一個介面,使所有繼承它的類都必須實現action方法,如下:
package uRLClassLoaderTest;
public interface ActionInterface {
public String action();
}
完成後生成class檔案,再將其打包為testInterface.jar檔案。
接下來新建一工程,為了編譯通過,引入之前打好的testInterface.jar包。並建立TestAction類,使它實現ActionInterface介面。如下:
package uRLClassLoaderTest;
import uRLClassLoaderTest.ActionInterface;
public class TestAction implements ActionInterface{
public String action()
{
return "this ActionTest class";
}
}
同樣,完成後生成class檔案,再將其打包為test.jar,放在c盤根目錄下。下面要做的就是利用URLClassLoader載入並執行TestAction的action方法,並將返回的值列印在控制檯上。
新建一工程,引入testInterface.jar包。並建立一可執行類(main方法),在其中加入如下程式碼:
package test;
import java.NET.*;
import java.io.*;
import actionInterface.ActionInterface;
public class ClassLoaderTest {
public static void main(String args[])
{
try
{
File file=new File("rtest.txt");
BufferedReader in=new BufferedReader(new FileReader(file));
String s=new String();
while((s=in.readLine())!=null)
{
URL url=new URL(s);
s=null;
URL url1=new URL("file:c:/test1.jar");
URLClassLoader myClassLoader=new URLClassLoader(new URL[]{url},Thread.currentThread().getContextClassLoader());
Class myClass=myClassLoader.loadClass("actionImplement.TestAction");
ActionInterface action=(ActionInterface)myClass.newInstance();
String str=action.action();
System.out.println(str);
URLClassLoader myClassLoader1=new URLClassLoader(new URL[]{url1},Thread.currentThread().getContextClassLoader());
Class myClass1=myClassLoader1.loadClass("actionImplement.TestAction");
ActionInterface action1=(ActionInterface)myClass1.newInstance();
String str1=action1.action();
System.out.println(str1);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
該程式碼先在該工程下建立一個檔案,用來儲存需要載入的jar的路徑,實現時,讀取一條路徑,載入一個