亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Class Loader

系統 1604 0

bootstrap Class Loaders負責裝載java.*下的基本類?
extension Class Loaders負責裝載javax.*下的類?
system Class Loaders負責系統(用戶)實現的類?

三者的關系是?
bootstrap class loaders是extension class loaders的父親?
extension class loaders是system class loaders的父親?

class loader的裝載機制是parent delegate的模型。即?
類的裝載是委托給父class loader去查找,如果沒有找到才用當前的class loader來查找。


http://a123159521.iteye.com/blog/1094986


ClassLoader應該是每一個Java程序員都必須了解的,但是我整整工作了四年才發現原來在這方面全是空白,現在在做模塊化,必須得了解這方面的知識,模塊間必須做隔離.?
以下是我這段時候的學習和總結,很多東西都是借網上的資料,JDK的ClassLoader的API,做如下總結:?
1.類加載器概述?
類加載器是一個對象,是負責加載類.在JVM是通過類加載器的調用LoadClass方法加載類對象.?
類加載器結構:?
1. 引導類加載器(bootstrap class loader):它用來加載 Java 的核心庫,是用原生代碼來實現的[null]?
2. 擴展類加載器(extensions class loader):它用來加載 Java 的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄里面查找并加載 Java 類[ExtClassLoader]?
3. 系統類加載器(system class loader):它根據 Java 應用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應用的類都是由它來完成加載的??梢酝ㄟ^ ClassLoader.getSystemClassLoader() 來獲取它[AppClassLoader]?
2.類加載器的工作流程?
Class Loader ?
當classLoader有類需要載入時,先讓其parent查找載入,如果parent找不到,再由自己搜索路徑進行載入。ClassLoader在運行期會以父/子的層次結構存在,每個classLoader 實例都有其父ClassLoader的引用,而父ClassLoader并沒有持有子ClassLoader的引用,從而形成一條單向鏈,當一個類裝載請求提交到某個ClassLoader時,默認的類裝載過程如下:?
?1. 檢查這個類有沒有被裝載過,如果已經裝載過,返回?
?2. 調用父ClassLoader去裝載類,如果裝載成功返回.?
?3. 調用自身的裝載類方法,如果裝載成功則返回?
?4. 如查都沒有成功,拋出ClassNotFoundException.?
簡單說,當ClassLoader鏈上的某一ClassLoader收到類裝載請求時,會按順序向上詢問其所有父節點,直到boot classLoader.任何一個節點成功受理了此請求,則返回,如果所有父節點都不能受理,這個時候才由請求的ClassLoader自身來裝載這個類,如果仍不能裝載,則拋出異常.?
3.Class的類加載器到底是哪個.?
類加載器在其應用場景的不同又可以分為如下類加載器:?
? 1. 系統 ClassLoader?
? 2. 調用者 ClassLoader?
? 3. 線程上下文ClassLoader?
這些類加載器主要是用于動態加載資源,也可以解決架包的重復問題.?
調用者類加載器 是指當前所在的類裝載時所使用的ClassLoader,它可能是SystemClassLoader, 也可能是一個自定義的ClassLoader.可以通過getClass().getClassLoader()來得到Caller ClassLoader.例如,存在類A,是被AClassLoader所加載,A.class.getClassloader()為AClassLoader的實例,它就是A.class的Caller Classloader.??
如果在A類中new一個B類,那么B類的類加載器就一定是AClassLoader嗎。答案是錯的。因為new一個對象,loadClass(B.class)可能在其父ClassLoader中就已經完成.?
決定一個類的類加載器是defineClass,而判斷兩個類是否為同一對象的標準里面有一條是類加載器必須為相同. ?
現在有一個問題,如何使用指定的ClassLoader去完成類和資源的加載呢,或者說,當需要去實例化一個調用者ClassLoader和它的父ClassLoader都不能加載的類時,怎么辦.?
一個典型的一例子是Jaxp,當使用xerces的Sax實現時,我們首先需要通過rt.jar中的java.xml.parsers.SaxparserFactory.getinstance()得到xeceImpl.jar中的org.apache.xerces.jaxp.SAXParserFactory.Impl的實例,由于Jaxp的框架接口的類位于Java_hom/lib/rt.jar中,由bootStrap ClassLoader裝載,處于ClassLoader層次結構中的最頂層,而xecesImpl.jar由低怪的ClassLoader裝載,也就是說SaxParserFactoryImpl是在SaxParserFactory中實例化的,如前所述,使用SaxParserFactory的CallerClassLoader(boot)是完成不了這個任務的.這里我們需要理解下線程上下文ClassLoader.?

線程上下文ClassLoader
. 每一個線程都有一個關聯的上下文ClassLoader.如果使用new Thread()方式生成新的線程,新線程將繼承其父線程的上下文ClassLoader.如果程序對線程上下文ClassLoader沒有任何改動的話,程序的所有線程將都使用System ClassLoader作為上下文ClassLoader.當使用Thread.currentThread().setContextClassLoader(classLoader)時,線程上下文ClassLoader就變成了指定的ClassLoader了。此時,在本線程的任意一處地方,調用Thread.currentThread().getContextClassLoader().都可以得到前面設置的ClassLoader.?
一個線程來了,第一件事情便是設置ClassLoader來設置線程上下文類加載器,模塊內部都使用線程上下文類加載器[比如某一接口處于AClassLoader,我設置AClassLoader為線程上下文類加載器,那么我通過getContextClassLoader就可以得到A類的類加載器,以后使用A類的類加載器,這樣就可以統一調用了]?
(有人可能會問了,我總不能每加載一個類,都使用上下文線程去加載吧,我笑了,其實這大可不必,只要你的類是你私有的[在當前類加載器父級加載器未加載過],就不需要重新加載)?

4.JVM工作流程?
Class Loader 加載流程?
? Jvm 建立=>初始化工作=>產生第一個ClassLoader,即boot?
? Boot ClassLoader在sum.misc.Launcher類里面的ExtClassLoader,并設置其Parent為Boot.?
? Boot ClassLoader載入sun.misc.Launcher$AppClassLoader,設定其parent為ExtClassLoader(但是AppClassLoader也是boot所載入)?
? AppClassLoader載入各個xx.class,xx.class也有可能被ExtClassLoader或者boot載入.?
? 自定義的ClassLoader的getparent()是AppClassLoader.parent和他的加載器沒有關系.?
? ExtClassLoader和AppClassLoader都是URLClassLoader的子類。?
? AppClassLoader的URL是由系統參數java.class.path取出的字符串決定,而java.class.path由運行機制java.exe時的-cp或-classpath或CLASSPATH環境變量決定?
? ExtClassLoader查找的url是系統變量java.ext.dirs,java.ext.dirs默認為jdk\jre\lib\ext?
? Bootstrap loader的查找url是sun.boot.class.path?
5.獨立應用的類加載器?
由于系統類加載器是JVM最后創建的類加載器,這樣代碼只會適應于簡單命令行啟動的程序。一旦代碼移植到EJB、Web應用或者Java Web Start應用程序中,程序肯定不能正確執行。?
因此一般只有兩種選擇,當前類加載器和線程上下文類加載器。當前類加載器是指當前方法所在類的加載器。這個類加載器是運行時類解析使用的加載器,Class.forName(String)和Class.getResource(String)也使用該類加載器。代碼中X.class的寫法使用的類加載器也是這個類加載器。?
Web應用和Java企業級應用中,應用服務器經常要使用復雜的類加載器結構來實現JNDI(Java命名和目錄接口)、線程池、組件熱部署等功能,因此理解這一點尤其重要。?

通常JVM中的類加載器是按照層次結構組織的,目的是每個類加載器(除了啟動整個JVM的原初類加載器)都有一個父類加載器。當類加載請求到來時,類加載器通常首先將請求代理給父類加載器。只有當父類加載器失敗后,它才試圖按照自己的算法查找并定義當前類。[如何覆蓋父類的加載機制]?

有時這種模式并不能總是奏效。這通常發生在JVM核心代碼必須動態加載由應用程序動態提供的資源時。拿JNDI為例,它的核心是由JRE核心類(rt.jar)實現的。但這些核心JNDI類必須能加載由第三方廠商提供的JNDI實現。這種情況下調用父類加載器(原初類加載器)來加載只有其子類加載器可見的類,這種代理機制就會失效[雙親委托機制]。?
解決辦法就是讓核心JNDI類使用線程上下文類加載器,從而有效的打通類加載器層次結構,逆著代理機制的方向使用類加載器。?

順便提一下,XML解析API(JAXP)也是使用此種機制。當JAXP還是J2SE擴展時,XML解析器使用當前累加載器方法來加載解析器實現。但當JAXP成為J2SE核心代碼后,類加載機制就換成了使用線程上下文加載器,這和JNDI的原因相似。?

但這在不同JVM線程共享數據來溝通時,就會使類加載器的結構亂七八糟。除非所有線程都使用同一個上下文類加載器。而且,使用當前類加載器已成為缺省規則,它們廣泛應用在類聲明、Class.forName等情景中。即使你想盡可能只使用上下文類加載器,總是有這樣那樣的代碼不是你所能控制的。這些代碼都使用代理到當前類加載器的模式?;祀s使用代理模式是很危險的。?
這種混亂的狀況還將在Java中存在很長時間。在J2SE中還包括以下的功能使用不同的類加載器:?
? JNDI使用線程上下文類加載器?
? Class.getResource()和Class.forName()使用當前類加載器?
? JAXP使用上下文類加載器?
? Java.unit.ResourceBundle使用調用者的當前類加載器?
? URL協議處理器使用java.protocol.handler.pkgs系統屬性并只使用系統類加載器?
? Java序列化API缺省使用調用者當前的類加載器.?
6.Tomcate類加載器的代理模式?
下面是對每個類加載器的定義:?
1.Bootstrap加載器在這里是Java里的Bootstrap和ExtClassLoader的總稱,負責加載Java核心包的類,和<Java_Home>/jre/lib/ext目錄下的類.通常我們開發人員并不關心.我想只要是java程序這些肯定是必要的?
2.System就是系統加載器,一般是AppClassLoader,負責加載ClassPath環境變量設置目錄下的值,這個我們開發人員會非常關注,但是在Tomcat里面,雖然用AppClassLoader類加載器,但我們設置的ClassPath對它沒有影響(如果有影響,那就麻煩了,將會導致Tomcat運行不穩定),為什么呢,因為tomcat每次啟動的時候都會在命令行窗口中都會重新設置Classpath值為:<catalina_Home>/bin/bootstrap.jar和<java_Home>/lib/tools.jar,所以這里面的類一般對應用程序不可見的.除非你設置了?
3.Common類加載器負責加載TomcatHOME/common/class下的.Class文件和common/lib中的jar包,這些類可以被Tomcat內核和每個Web應用程序都可以看見,一般放公用的一些重要的類,如servlet.jar等?
4.Catalina類加載器從server/classes和server/lib下加載類,Catalina加載的類只對Tomcat服務器內核可見,對Web應用程序不可見,對于運行Tomcat內核的線程,它的上下文類加載器就是Catalina類加載器?
5.Shared類加載器負責從share/classes和share/lib中加載類,它加載的類只對所有Web應用程序有效,對Tomcat不可見.?
6.WebappX類加載器負責加載Web應用程序的/web-INF/classes和lib目錄下的類,只對當前Web應用程序有效,對其他Web應用程序無效,對于運行每個Web應用程序的線程,他們的上下文類加載器就是它們各自的WebappX類加載器?
7.自定義類加載器?
通過ClassLoader的子類動態加載class文件,體現java動態實時類裝入特性:?
ClassLoader有兩種載入方式:?
? Pre-loading 預先載入,載入的基礎類?
? Load-on-demand 按需載入,只有實例化一個類才會被classloader載入,僅僅聲有不會被載入.?
Static 何時執行:?
? 當調用forName(String)載入class時執行,如果調用ClassLoader.loadClass不會執行,forName(String,false,ClassLoader)也不會執行.?
? 如果在載入class時沒有執行static塊,則在第一次實例化時執行,比如new,Class.newInstance()操作.?
? Static塊僅執行一次?


Class Loader ?

當使用java 去執行一個類的時候,JVM使用applicationClassLoader加載這個類,如果A類引用了B類,不管是直接引用,還是class.forName()引用,JVM會找到加載A類的classLoader,并使用這個ClassLoader加載B類.?
注意:JVM加載類A,并使用A的ClassLoader去加載B,但B的類加載器并不一定和A的類加載器一致.?
使用java –verbos:class Main運行一個程序,加載如下:?
1. 加載java*下的類?

Class Loader ?

2. 加載自定義的類?


Class Loader ?
只要當程序運行到B了,需要加載B了,JVM才會去加載這個類?

隱式加載?
這里的B就是引用類,發生由于引用,實例化或繼承導致需要裝載類的時候,隱式類裝載是在幕后啟動的,JVM會解析必要的引用并裝載類.?
顯式加載?
1. Java.lang.Class.forName()方法加載?
a) Public static Class forName(String classname)?
b) Public static Class forName(String className,Boolean ini,ClassLoader loader)?
參數說明:?
className 所需類的完全限定名?
ini 是否必須初始化類(靜態代理初始化)?
loader – 用于加載類的類加載器?
調用只有一個參數的相當于Class.forName(className,true,loader);?
這里的loader 為callerClassLoader,就是調用者類加載器.?

不管使用的是new來實例化某個類,或是使用只有一個參數的forName()方法,內部矛盾都隱含了“載入類+運行靜態代碼塊”的步驟。而使用三個參數的,如果第二個參數為false,那么類加載器只會加載類,而不會初始化靜態代碼塊.只有實例化類時,才會執行.不過靜態代碼只執行一次.?
以上是使用自定義加載器必須了解的.自定義加載器見下一篇?

Class Loader


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 九九在线观看高清免费 | 欧美视频一区二区专区 | 国产精品日本一区二区在线看 | 亚洲欧美日产综合一区二区三区 | 精品国产免费观看一区 | 日韩欧美色视频在线观看 | 在线理论视频 | 久久大香伊蕉在人线国产昨爱 | 久久99国产精品久久99小说 | 欧美日韩精品一区二区三区 | 九九视频精品全部免费播放 | 亚洲最大成人网 色香蕉 | 国产麻豆va精品视频 | 国产99视频在线 | 成年女人看片免费视频频 | 亚洲 欧美 日韩 在线 香蕉 | 国产毛片一区二区三区 | 久久久夜| 五月婷婷婷婷婷 | 四虎影院免费观看视频 | 国产一级特黄a大片免费 | 欧美aaaa在线观看视频免费 | 国产农村一一级特黄毛片 | 激情婷婷成人亚洲综合 | 国产精品久久久视频 | 亚洲黄色在线看 | 四虎在线观看免费视频 | 四虎国产永久免费久久 | 天天色天天射综合网 | 久久久久久久久久鸭 | 久夜色精品国产一区二区三区 | 国产一区二区三区在线视频 | 国产亚洲美女精品久久久 | 狠色狠色狠狠色综合久久 | 欧美另类高清xxxxx | 亚洲欧美中文在线观看4 | 猫咪视频成人永久免费观看 | 天天操夜夜摸 | 欧美激情级毛片 | 成人a大片高清在线观看 | 美日韩免费视频 |