小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

URLClassLoader加載class到當(dāng)前線程類加載器 - 六月天 - BlogJava

 shaobin0604@163.com 2006-08-30

URLClassLoader加載class到當(dāng)前線程類加載器

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

下面來看一個例子,在該例子中,我們要完成的工作是利用URLClassLoader加載jar并運(yùn)行其中的類的某個方法。

首先我們定義一個接口,使所有繼承它的類都必須實(shí)現(xiàn)action方法,如下:

public   interface  ActionInterface  {
    
public  String action();
}

完成后將其打包為testInterface.jar文件。

接下來新建一工程,為了編譯通過,引入之前打好的testInterface.jar包。并創(chuàng)建TestAction類,使它實(shí)現(xiàn)ActionInterface接口。如下:

 

public   class  TestAction  implements  ActionInterface  {
    
public  String action()  {
        
return   " com.mxjava.TestAction.action " ;
    }

}

完成后將其打包為test.jar,放在c盤根目錄下。下面要做的就是利用URLClassLoader加載并運(yùn)行TestAction的action方法,并將返回的值打印在控制臺上。

新建一工程,引入testInterface.jar包。并創(chuàng)建一可執(zhí)行類(main方法),在其中加入如下代碼:

URL url  =   new  URL(“file:C: / test.jar”);
URLClassLoader myClassLoader 
=   new  URLClassLoader( new  URL[]  { url } );
Class myClass 
=  myClassLoader.loadClass(“com.mxjava.TestAction”);
ActionInterface action 
=  (ActionInterface)myClass.newInstance();
System.out.println(action.action());

  在上面的例子中,首先利用URLClassLoader加載了C:\test.jar包,將其中的com.mxjava.TestAction類載入內(nèi)存,將其強(qiáng)制轉(zhuǎn)型為testInterface包中的ActionInterface類型,最后調(diào)用其action方法,并打印到控制臺中。

  執(zhí)行程序后,在控制臺上如期打印出我們想要的內(nèi)容。但是,事情并沒有那么簡單,當(dāng)我們將該代碼移動web應(yīng)用中時,就會拋出異常。原來,Java為我們提供了三種可選擇的ClassLoader:
1. 系統(tǒng)類加載器或叫作應(yīng)用類加載器 (system classloader or application classloader)
2. 當(dāng)前類加載器
3. 當(dāng)前線程類加載器

  在上例中我們使用javac命令來運(yùn)行該程序,這時候使用的是系統(tǒng)類加載器 (system classloader)。這個類加載器處理 -classpath下的類加載工作,可以通過ClassLoader.getSystemClassLoader()方法調(diào)用。 ClassLoader 下所有的 getSystemXXX()的靜態(tài)方法都是通過這個方法定義的。在代碼中,應(yīng)該盡量少地調(diào)用這個方法,以其它的類加載器作為代理。否則代碼將只能工作在簡單的命令行應(yīng)用中。當(dāng)在web應(yīng)用中時,服務(wù)器也是利用ClassLoader來加載class的,由于ClassLoader的不同,所以在強(qiáng)制轉(zhuǎn)型時JVM認(rèn)定不是同一類型。(在JAVA中,一個類用其完全匹配類名(fully qualified class name)作為標(biāo)識,這里指的完全匹配類名包括包名和類名。但在JVM中一個類用其全名和一個加載類ClassLoader的實(shí)例作為唯一標(biāo)識。因此,如果一個名為Pg的包中,有一個名為Cl的類,被類加載器KlassLoader的一個實(shí)例kl1加載,Cl的實(shí)例,即C1.class在JVM中表示為(Cl, Pg, kl1)。這意味著兩個類加載器的實(shí)例(Cl, Pg, kl1) 和 (Cl, Pg, kl2)是不同的,被它們所加載的類也因此完全不同,互不兼容的。)為了能夠使程序正確運(yùn)行,我們首要解決的問題就是,如何將URLClassLoader加載的類,同當(dāng)前ClassLoader保持在同一類加載器中。解決方法很簡單,利用java提供的第三種ClassLoader—當(dāng)前線程類加載器即可。jdk api文檔就會發(fā)現(xiàn),URLClassLoader提供了三種構(gòu)造方式:

// 使用默認(rèn)的委托父 ClassLoader 為指定的 URL 構(gòu)造一個新 URLClassLoader。 
URLClassLoader(URL[] urls) 
// 為給定的 URL 構(gòu)造新 URLClassLoader。 
URLClassLoader(URL[] urls, ClassLoader parent) 
// 為指定的 URL、父類加載器和 URLStreamHandlerFactory 創(chuàng)建新 URLClassLoader。
URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) 

接下來要做的就是,在構(gòu)造URLClassLoader時,將當(dāng)前線程類加載器置入即可。如下:

URLClassLoader myClassLoader  =   new  URLClassLoader( new  URL[]  { url } , Thread.currentThread().getContextClassLoader());

總結(jié):
  
Java是利用ClassLoader來加載類到內(nèi)存的,ClassLoader本身是用java語言寫的,所以我們可以擴(kuò)展自己的ClassLoader。利用URLClassLoader可以加載指定jar包中的類到內(nèi)存。在命行上利用URLClassLoader加載jar時,是使用系統(tǒng)類加載器來加載class的,所以在web環(huán)境下,就會出錯。這是因?yàn)镴VM中一個類用其全名和一個加載類ClassLoader的實(shí)例作為唯一標(biāo)識的。我們只要利用URLClassLoader的第二種構(gòu)造方法并傳入當(dāng)前線程類加載器即可解決。

參考:
http://www./sharajava/archive/2006/07/25/59946.html
http://kb.csdn.net/java/Articles/200510/a1843d60-05b1-456f-9f72-811cb45ea4ae.html

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多