欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Class Loader

系統(tǒng) 1659 0

bootstrap Class Loaders負(fù)責(zé)裝載java.*下的基本類?
extension Class Loaders負(fù)責(zé)裝載javax.*下的類?
system Class Loaders負(fù)責(zé)系統(tǒng)(用戶)實現(xiàn)的類?

三者的關(guān)系是?
bootstrap class loaders是extension class loaders的父親?
extension class loaders是system class loaders的父親?

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


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


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

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

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

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

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

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

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


Class Loader ?

當(dāng)使用java 去執(zhí)行一個類的時候,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 ?
只要當(dāng)程序運行到B了,需要加載B了,JVM才會去加載這個類?

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

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

Class Loader


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品久久成人免费第三区 | ak福利视频| 欧美性视频网 | 亚洲 欧美 日韩 在线 | 激情丁香开心久久综合 | 国产精品视频免费 | 久久久久免费 | 很黄很粗很湿很刺激的视频 | 国产网站大全 | 91精品久久久久久久久网影视 | 亚洲精品第一国产综合高清 | 免费高清av| 欧美日韩精品久久久免费观看 | 一级美女 | 99久久精品国产自免费 | 日韩在线播放网址 | 青娱乐精品在线 | 意大利av在线 | 老色鬼a∨在线视频在线观看 | 国产欧美日韩一区二区三区四区 | 久久婷婷av | 精品亚洲永久免费精品 | 欧美日韩在线播放一区二区三区 | 一级做a爰片性色毛片中国 日本黄色免费片 | 久久久无码精品一区二区三区 | 特级全黄一级毛片免费 | 欧美一a一片一级一片 | 仇爱电视剧泰剧在线观看免费播放 | 精品久久久久一区二区三区 | 欧美精品网站 | 欧美在线观看a | 夜干夜干2017最新网站 | 亚洲福利在线观看 | 日韩大片在线 | 天天综合国产 | 亚洲香蕉毛片久久网站老妇人 | 中文字幕人成乱码在线观看 | 欧美18 - 19sex性 | 欧美jizzjizz在线播放 | 欧美中文在线观看 | 成人a视频片在线观看免费 中文字幕三区 |