<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    瘋狂

    STANDING ON THE SHOULDERS OF GIANTS
    posts - 481, comments - 486, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    classloader

    Posted on 2009-11-02 15:04 瘋狂 閱讀(650) 評論(0)  編輯  收藏 所屬分類: java

    什么是ClassLoader

    ClassLoader是一個抽象類,我們用它的實例對象來裝載類,它負責將 Java 字節碼裝載到 JVM 中, 并使其成為 JVM 一部分。 JVM 的類動態裝載技術能夠在運行時刻動態地加載或者替換系統的某些功能模塊,而不影響系統其他功能模塊的正常運行。一般是通過類名讀入一個class文件來裝載這個類,(其它加載形式暫時沒有研究過)。

    JAVA一般用三個class loader完成類的裝載任務(自己定義的class loader出外),它們是Bootstrap Loader、ExtClassLoader和AppClassLoader,最后一個也被SUN稱為system class loader。它們的組織方式是:先由Bootstrap Loader生成ExtClassLoader,并設置ExtClassLoader的parent為null(其實準確得說其parent是Bootstrap Loader,但因為Bootstrap Loader由C++寫成,并不是邏輯意義上的JAVA類,所以只能為null);然后Bootstrap Loader生成AppclassLoader,設置其parent為ExtClassLoader

    類的裝載采用的是代理模式:裝載一個類時先由AppClassLoader或自己定義的class loader請求其parent裝載,parent再請求它的parent,這樣到了頂級,也就是Bootstrap Loader,如果parent looder找到了要裝載的類,就由parent loader裝載,否則就由它的"下級"去干這件事。這樣就一級級委托知道把類找到裝載完畢。要說明的是ExtClassLoader和 AppClassLoader都是URLClassLoader的子類,而URLClassLoader可由一個URL對象確定它尋找類的路徑,我們可以通過下面的方法發現前述的三種class loader的搜尋路徑:

    • System.out.println(System.getProperty("sun.boot.class.path"))
    • System.out.println(System.getProperty("java.class.path"))
    • System.out.println(System.getProperty("java.ext.dirs"))

    ClassLoader裝載過程

    類裝載就是尋找一個類或是一個接口的字節碼文件并通過解析該字節碼來構造代表這個類或是這個接口的 class 對象的過程。在 Java 中,類裝載器把一個類裝入 Java 虛擬機中,要經過三個步驟來完成:裝載、鏈接和初始化,其中鏈接又可以分成校驗、準備和解析三步,除了解析外,其它步驟是嚴格按照順序完成的,各個步驟的主要工作如下:

    1.        裝載:查找和導入類或接口的字節碼;

    2.        鏈接:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的;

    l        校驗:檢查導入類或接口的二進制數據的正確性;

    l        準備:給類的靜態變量分配并初始化存儲空間;

    l        解析:將符號引用轉成直接引用;

    3.        初始化:激活類的靜態變量的初始化 Java 代碼和靜態 Java 代碼塊。

    裝載的實現

    JVM 中類的裝載是由 ClassLoader 和它的子類來實現的。 Java ClassLoader 是一個重要的 Java 運行時系統組件,它負責在運行時查找和裝入 Java 字節碼。

    Java 中, ClassLoader 是一個抽象類,它在包 java.lang 中。可以這樣說,只要了解了 ClassLoader 中的一些重要的方法,再結合上面所介紹的 JVM 中類裝載的具體的過程,對動態裝載類這項技術就有了一個比較大概的掌握,這些重要的方法包括以下幾個:

    1.        loadCass 方法: loadClass(String name ,boolean resolve) 其中 name 參數指定了 JVM 需要的類的名稱 , 該名稱以類的全限定名表示,如 Java.lang.Object resolve 參數告訴方法是否需要解析類,在初始化類之前,應考慮類解析,并不是所有的類都需要解析,如果 JVM 只需要知道該類是否存在或找出該類的超類,那么就不需要解析。這個方法是 ClassLoader 的入口點。

    2.        defineClass 方法   這個方法接受類文件的字節數組并把它轉換成 Class 對象。字節數組可以是從本地文件系統或網絡裝入的數據。它把字節碼分析成運行時數據結構、校驗有效性等等。

    3.        findSystemClass 方法   findSystemClass 方法從本地文件系統裝入 Java 字節碼。它在本地文件系統中尋找類文件,如果存在,就使用 defineClass 將字節數組轉換成 Class 對象。當運行 Java 應用程序時 , 這是 JVM 正常裝入類的缺省機制。

    4.        resolveClass 方法 resolveClass(Class c) 方法解析裝入的類,如果該類已經被解析過那么將不做處理。當調用 loadClass 方法時 , 通過它的 resolve 參數決定是否要進行解析。

    5.        findLoadedClass 方法   當調用 loadClass 方法裝入類時 , 調用 findLoadedClass 方法來查看 ClassLoader 是否已裝入這個類 , 如果已裝入 , 那么返回 Class 對象 , 否則返回 NULL 。如果強行裝載已存在的類 , 將會拋出鏈接錯誤。

    java.lang.Class類

    某 個類的所有實例內部都有一個引用,指向該類對應的Class的實例的位置,每個java類對應的Class實例可以當作是類在內存中的代理人。所以當要獲 得類的信息(如有哪些類變量,有哪些方法)時,都可以讓類對應的Class的實例代勞.java的Reflection機制就大量的使用這種方法來實現。 但是Class類無法手工實例化,當載入任意類的時候自動創建一個該類對應的Class的實例。每個java類都是由某個classLoader (ClassLoader的實例)來載入的,因此Class類別的實例中都會他的ClassLoader的實例的引用。可以通過 getClass.getClassLoader()得到CLassLoader的實例。

    java動態載入class的兩種方式:
    1)implicit隱式,即利用實例化才載入的特性來動態載入class
    2)explicit顯式方式,又分兩種方式:
    a)java.lang.Class的forName()方法
    b)java.lang.ClassLoader的loadClass()方法

    各種java類由哪些classLoader加載?

    1)java類可以通過實例.getClass.getClassLoader()得到
    2)接口由AppClassLoader(SystemClassLoader)載入 ,SystemClassLoader:可以由ClassLoader.getSystemClassLoader()獲得實例
    3)ClassLoader類由bootstrap loader載入

    ClassLoader hierachy:

    1)jvm初始化產生bootstrap loader。并設定它的父ClassLoader為null

    2)bootstrap loader建立AppClassLoader,載入 運行java.exe時 的-cp或-classpath中的類(每個運行中的線程都有一個成員contextClassLoader,用來在運行時動態地載入其它類系統默認的 contextClassLoader是systemClassLoader)

    Java 類裝載的代理結構

    (Bootstrap) 裝載器:該裝載器沒有父裝載器,它是 JVM 實現的一部分,從 sun.boot.class.path 裝載運行時庫的核心代碼。

     

    擴展 (Extension) 裝載器:繼承的父裝載器為根裝載器,不像根裝載器可能與運行時的操作系統有關,這個類裝載器是用純 Java 代碼實現的,它從 java.ext.dirs ( 擴展目錄 ) 中裝載代碼。

    系統 (System or Application) 裝載器:裝載器為擴展裝載器,我們都知道在安裝 JDK 的時候要設置環境變量 (CLASSPATH ) ,這個類裝載器就是從 java.class.path(CLASSPATH 環境變量 ) 中裝載代碼的,它也是用純 Java 代碼實現的,同時還是用戶自定義類裝載器的缺省父裝載器。

    小應用程序 (Applet) 裝載器:父裝載器為系統裝載器,它從用戶指定的網絡上的特定目錄裝載小應用程序代碼。

    java中的代理結構是自上而下查找類的,這與很多web裝載器不同。

    tomcat中的實現的子ClassLoader的結構

    Tomcat Server在啟動的時候將構造一個ClassLoader樹,以保證模塊的類庫是私有的
    Tomcat Server的ClassLoader結構如下:


           ---------------------------+
           |         Bootstrap           |
           |             |               |
           |          System             |
           |             |               |
           |          Common             |
           |         /      \            |
           |     Catalina  Shared        |
           |               /    \        |
           |          WebApp1  WebApp2   |
           ---------------------------+

    其中:
    - Bootstrap - 載入JVM自帶的類和$JAVA_HOME/jre/lib/ext/*.jar
    - System - 載入$CLASSPATH/*.class
    - Common - 載入$CATALINA_HOME/common/...,它們對TOMCAT和所有的WEB APP都可見
    - Catalina - 載入$CATALINA_HOME/server/...,它們僅對TOMCAT可見,對所有的WEB APP都不可見
    - Shared - 載入$CATALINA_HOME/shared/...,它們僅對所有WEB APP可見,對TOMCAT不可見(也不必見)
    - WebApp? - 載入ContextBase?/WEB-INF/...,它們僅對該WEB APP可見

    ClassLoader被組織成樹形,一般的工作原理是:
    1) 線程需要用到某個類,于是contextClassLoader被請求來載入該類
    2) contextClassLoader請求它的父ClassLoader來完成該載入請求
    3) 如果父ClassLoader無法載入類,則contextClassLoader試圖自己來載入


    注意:WebApp?ClassLoader的工作原理和上述有少許不同:
    它先試圖自己載入類(在ContextBase?/WEB-INF/...中載入類),如果無法載入,再請求父ClassLoader完成

    主站蜘蛛池模板: 成人免费视频77777| 亚洲av成人一区二区三区| 成年性午夜免费视频网站不卡| 国产成人无码精品久久久久免费| 亚洲中文字幕在线无码一区二区 | 亚洲av日韩综合一区久热| 亚洲毛片在线观看| 中文亚洲成a人片在线观看| 永久免费视频v片www| 成年人视频免费在线观看| 国产无遮挡无码视频免费软件 | 亚洲人成无码www久久久| 噜噜嘿在线视频免费观看| 1000部拍拍拍18勿入免费凤凰福利| 9久久免费国产精品特黄| 美国免费高清一级毛片| 亚洲日韩国产一区二区三区在线| 日韩精品亚洲人成在线观看| 亚洲日韩中文无码久久| 亚洲福利精品电影在线观看| 国产又粗又猛又爽又黄的免费视频| 国产精品成人免费视频网站京东| 91久久精品国产免费直播| 日本免费中文视频| 国产啪精品视频网站免费尤物| 一级做a爰性色毛片免费| 老司机精品视频免费| 国产青草亚洲香蕉精品久久| 亚洲精品无码永久在线观看男男| 激情内射亚洲一区二区三区爱妻| 亚洲精品无码久久久久久久 | 最近免费中文字幕大全免费版视频| 在线观看片免费人成视频无码 | 久久久久亚洲AV综合波多野结衣 | 亚洲一区二区三区在线| 亚洲一级毛片免观看| 亚洲综合色区中文字幕| 亚洲一区中文字幕在线观看| 亚洲国产精品综合久久20| 亚洲精品123区在线观看| 亚洲欧美日韩综合俺去了|