類加載器主要分爲兩類,一類是 JDK 默認提供的,一類是用戶自定義的。 JDK 默認提供三種類加載器:html
Bootstrap ClassLoader
啓動類加載器:每次執行 java
命令時都會使用該加載器爲虛擬機加載核心類。該加載器是由 native code
實現,而不是 Java 代碼,加載類的路徑爲 <JAVA_HOME>/jre/lib
。特別的 <JAVA_HOME>/jre/lib/rt.jar
中包含了 sun.misc.Launcher
類, 而 sun.misc.Launcher$ExtClassLoader
和 sun.misc.Launcher$AppClassLoader
都是 sun.misc.Launcher
的內部類,因此拓展類加載器和系統類加載器都是由啓動類加載器加載的。Extension ClassLoader
, 拓展類加載器:用於加載拓展庫中的類。拓展庫路徑爲 <JAVA_HOME>/jre/lib/ext/
。實現類爲 sun.misc.Launcher$ExtClassLoader
System ClassLoader
系統類加載器:用於加載 CLASSPATH 中的類。實現類爲 sun.misc.Launcher$AppClassLoader
歡迎學Java和大數據的朋友們加入java架構交流: 855835163
java
羣內提供免費的架構資料還有:Java工程化、高性能及分佈式、高性能、深刻淺出。高架構。性能調優、Spring,MyBatis,Netty源碼分析和大數據等多個知識點高級進階乾貨的免費直播講解 能夠進來一塊兒學習交流哦
Custom ClassLoader
, 通常都是 java.lang.ClassLoder
的子類正統的類加載機制是基於雙親委派的,也就是當調用類加載器加載類時,首先將加載任務委派給雙親,若雙親沒法加載成功時,本身才進行類加載。web
在實例化一個新的類加載器時,咱們能夠爲其指定一個 parent
,即雙親,若未顯式指定,則 System ClassLoader
就做爲默認雙親。apache
具體的說,類加載任務是由 ClassLoader
的 loadClass()
方法來執行的,他會按照如下順序加載類:bootstrap
findLoadedClass()
看該類是否已經被加載。該方法爲 native code 實現,若已加載則返回。parent.loadClass()
,若成功則返回。findClass()
方法加載類。java.lang.ClassLoader
中該方法只是簡單的拋出一個 ClassNotFoundException
因此,自定義的 ClassLoader 都須要 Override findClass()
方法。java.lang.ClassLoader
ClassLoader
是一個抽象類。The Java™ Language Specification
定義的全類名,全類名的定義請查閱 The Form of a Binary。Class.getClassLoader()
方法返回的是數組元素的類加載器,若數組元素是基本類型,則返回 null
,若類是由 Bootstrap ClassLoader
加載的話也是返回 null。
1數組 2tomcat 3安全 4服務器 5架構 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
ClassLoader
默認支持並行加載,可是其子類必須調用 ClassLoader.registerAsParallelCapable()
來啓用並行加載defineClass()
方法能夠將字節流轉換成一個 Class
對象。而後調用 Class.newInstance()
來建立類的實例java.security.SecureClassLoader
增長了一層權限驗證,由於關注點不在安全,因此暫不討論。
java.net.URLClassLoader
該類加載器用來加載 URL 指定的 JAR 文件或目錄中的類和資源,以 /
結尾的 URL 認爲是目錄,不然認爲是 JAR 文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Tomcat 使用正統的類加載機制(雙親委派),但部分地方作了改動。
Bootstrap classLoader
和 Extension classLoader
的做用不變。System classLoader
正常狀況下加載的是 CLASSPATH
下的類,可是 Tomcat 的啓動腳本並未使用該變量,而是從如下倉庫下加載類:$CATALINA_HOME/bin/bootstrap.jar
包含了 Tomcat 的啓動類。在該啓動類中建立了 Common classLoader
、Catalina classLoader
、shared classLoader
。由於 $CATALINA_BASE/conf/catalina.properties
中只對 common.loader
屬性作了定義,server.loader
和 shared.loader
屬性爲空,因此默認狀況下,這三個 classLoader 都是 CommonLoader
。具體的代碼邏輯能夠查閱 org.apache.catalina.startup.Bootstrap
類的 initClassLoaders()
方法和 createClassLoader()
方法。$CATALINA_BASE/bin/tomcat-juli.jar
包含了 Tomcat 日誌模塊所須要的實現類。$CATALINA_HOME/bin/commons-daemon.jar。
Common classLoader
是位於 Tomcat 應用服務器頂層的公用類加載器。由其加載的類能夠由 Tomcat 自身類和全部應用程序使用。掃描路徑由 $CATALINA_BASE/conf/catalina.properties
文件中的 common.loader
屬性定義。默認是 $CATALINA_HOME/lib。
catalina classLoader
用於加載服務器內部可見類,這些類應用程序不能訪問。shared classLoader
用於加載應用程序共享類,這些類服務器不會依賴。Webapp classLoader
。每一個應用程序都會有一個獨一無二的 webapp classloader
,他用來加載本應用程序 /WEB-INF/classes
和 /WEB-INF/lib
下的類。特別的:
Webapp classLoader
的默認行爲會與正常的雙親委派模式不一樣:
Bootstrap classloader
加載。/WEB-INF/classes
加載。/WEB-INF/lib/*.jar
加載。System
、Common
、shared
加載(該步驟使用雙親委派)。固然了,咱們也能夠經過配置來使 Webapp classLoader
嚴格按照雙親委派模式加載類:
META-INF/context.xml
(和 WEB-INF/classes
在同一目錄下) 配置文件中添加 <Loader delegate="true"/>
Webapp classLoader
的實現類是 org.apache.catalina.loader.WebappLoader
,他有一個屬性叫 delegate
, 用來控制類加載器的加載行爲,默認爲 false
,咱們可使用 set
方法,將其設爲 true
來啓用嚴格雙親委派加載模式。嚴格雙親委派模式加載步驟:
Bootstrap classloader
加載。System
、Common
、shared
加載。/WEB-INF/classes
加載。/WEB-INF/lib/*.jar
加載。歡迎學Java和大數據的朋友們加入java架構交流: 855835163 羣內提供免費的架構資料還有:Java工程化、高性能及分佈式、高性能、深刻淺出。高架構。性能調優、Spring,MyBatis,Netty源碼分析和大數據等多個知識點高級進階乾貨的免費直播講解 能夠進來一塊兒學習交流哦