ClassLoader類加載機制

ClassLoader

作用

ClassLoader是用來動態(tài)加載class文件到內(nèi)存中。

JAVA默認(rèn)提供三個classLoader
  1. BootStrap ClassLoader:啟動類加載器蹋绽,負(fù)責(zé)加載JDK中的核心類庫昧互。
  2. Extension ClassLoader:擴展類加載器,負(fù)責(zé)加載JAVA的擴展類庫薪介。
  3. App ClassLoader: 系統(tǒng)類加載器祠饺, 加載應(yīng)用程序classpath目錄下的所有jar和class文件。
  4. 自定義類加載器

ClassLoader類加載的原理

ClassLoader使用雙親委托來搜索類汁政,每一個ClassLoader實例都有一個父類加載器的引用道偷。

當(dāng)一個ClassLoader實例需要加載某個類時缀旁,會在親自搜索這個類之前,先把任務(wù)委托給父類加載器勺鸦,這個過程時由上至下的并巍。

首先由最頂層的類加載器BootStrap ClassLoader試圖加載,如果沒有加載到换途,則把任務(wù)轉(zhuǎn)交給Extension ClassLoader加載懊渡。

如果也沒加載到,則轉(zhuǎn)交給App ClassLoader進(jìn)行加載军拟。

如果也沒加載到剃执,則返回給委托的發(fā)起者,由它到指定的文件系統(tǒng)或者網(wǎng)絡(luò)等URL中加載該類懈息。

如果都沒有加載到這個類肾档,就拋出ClassNotFoundException異常。

否則將這個找到的類生成一個類的定義辫继,并將它加載到內(nèi)存中怒见,最后返回這個類在內(nèi)存中的Class實例對象。

使用原因

可以避免重復(fù)加載骇两,因為當(dāng)父類加載了該類的時候速种,子ClassLoader就沒有必要重新加載一次。

如果不使用這種委托模式低千,當(dāng)用戶可以使用自定義String來動態(tài)替換java核心api中定義的類型配阵。

而雙親委托的方式可以避免這種情況,因為String在啟動時已經(jīng)被BootStrap ClassLoader加載示血,用戶自定義的ClassLoader永遠(yuǎn)無法加載一個自己寫的String棋傍,除非改變JDK中ClassLoader搜索類的默認(rèn)算法。

JVM在搜索類的時候是如何判斷兩個Class是相同的难审?

不僅需要判斷兩個類的類名是否相同瘫拣,而且要判斷是否由同一個類加載器實例加載。只有同時滿足兩種情況告喊,JVM才認(rèn)為兩個Class是相同的麸拄。

就算兩個class是同一份class字節(jié)碼,如果被兩個不同的ClassLoader實例加載黔姜,JVM也會認(rèn)為是兩個不同的class拢切。

ClassLoader的體系架構(gòu)

classloader structure

定義自己的ClassLoader

JAVA提供了默認(rèn)的ClassLoader,為什么要定義自己的類加載器秆吵?

因為JAVA提供的默認(rèn)ClassLoader只加載指定目錄下的jar和Class淮椰,如果想加載其他位置的類或jar時,就需要定義自己的ClassLoader。目前的web服務(wù)器中都定義了自己的類加載器主穗,用于加載web應(yīng)用制定目錄下的類庫(jar或class)泻拦,入weblogic、Jboss忽媒、tomcat等争拐。

例子:

1、新建一個web工程httpweb

2晦雨、新建一個ClassLoaderServletTest陆错,用于打印web容器中的ClassLoader層次結(jié)構(gòu)

import java.io.IOException;  
import java.io.PrintWriter;  

import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
   
public class ClassLoaderServletTest extends HttpServlet {  
   
     public void doGet(HttpServletRequest request, HttpServletResponse response)  
     throws ServletException, IOException {  
 
         response.setContentType("text/html");  
         PrintWriter out = response.getWriter();  
         ClassLoader loader = this.getClass().getClassLoader();  
         while(loader != null) {  
             out.write(loader.getClass().getName()+"<br/>");  
             loader = loader.getParent();  
         }  
         out.write(String.valueOf(loader));  
         out.flush();  
         out.close();  
     }  
       
     public void doPost(HttpServletRequest request, HttpServletResponse response)  
             throws ServletException, IOException {  
         this.doGet(request, response);  
     }  
   
 }  

3、配置Servlet金赦,并啟動服務(wù)

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="2.4"   
     xmlns="http://java.sun.com/xml/ns/j2ee"   
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
   <servlet>  
     <servlet-name>ClassLoaderServletTest</servlet-name>  
     <servlet-class>ClassLoaderServletTest</servlet-class>  
   </servlet>  
   
   <servlet-mapping>  
     <servlet-name>ClassLoaderServletTest</servlet-name>  
     <url-pattern>/servlet/ClassLoaderServletTest</url-pattern>  
   </servlet-mapping>  
   <welcome-file-list>  
     <welcome-file>index.jsp</welcome-file>  
   </welcome-file-list>  
</web-app>  

4音瓷、訪問Servlet,獲得顯示結(jié)果

tomcat-classLoader

定義自己的類加載器分為兩步:

  1. 繼承java.lang.ClassLoader
  2. 重寫父類的findClass方法

當(dāng)JDK中的loadClass方法搜索不到類時夹抗,loadClass方法就會調(diào)用findClass方法搜索類绳慎,所以只需要重寫該方法即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漠烧,一起剝皮案震驚了整個濱河市杏愤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌已脓,老刑警劉巖珊楼,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異度液,居然都是意外死亡厕宗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門堕担,熙熙樓的掌柜王于貴愁眉苦臉地迎上來已慢,“玉大人,你說我怎么就攤上這事霹购∮踊荩” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵齐疙,是天一觀的道長膜楷。 經(jīng)常有香客問我,道長贞奋,這世上最難降的妖魔是什么赌厅? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮忆矛,結(jié)果婚禮上察蹲,老公的妹妹穿的比我還像新娘。我一直安慰自己催训,他們只是感情好洽议,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著漫拭,像睡著了一般亚兄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上采驻,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天审胚,我揣著相機與錄音,去河邊找鬼礼旅。 笑死膳叨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的痘系。 我是一名探鬼主播菲嘴,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼汰翠!你這毒婦竟也來了龄坪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤复唤,失蹤者是張志新(化名)和其女友劉穎健田,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佛纫,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡妓局,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呈宇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跟磨。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖攒盈,靈堂內(nèi)的尸體忽然破棺而出抵拘,到底是詐尸還是另有隱情,我是刑警寧澤型豁,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布僵蛛,位于F島的核電站,受9級特大地震影響迎变,放射性物質(zhì)發(fā)生泄漏充尉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一衣形、第九天 我趴在偏房一處隱蔽的房頂上張望驼侠。 院中可真熱鬧姿鸿,春花似錦、人聲如沸倒源。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笋熬。三九已至热某,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胳螟,已是汗流浹背昔馋。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糖耸,地道東北人秘遏。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像嘉竟,于是被迫代替她去往敵國和親垄提。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345