【Java類加載器】
JavaClassloader是Java運行時環境(Java Runtime Environment)的一部分,負責動態加載Java類到Java虛擬機的內存空間中。
類通常是按需加載,即第一次使用該類時才加載。由於有了類加載器,Java運行時系統不需要知道文件與文件系統。
JVM有三種類加載器:
1.啓動類加載器(Bootstrap):是在jvm啓動時創建的類加載器。它負責將(jre/lib)下面的核心類庫或-Xbootclasspath選項指定的jar包加載到內存中。
2.擴展類加載器(Extension):是由Sun的ExtClassLoader(sun.misc.Launcher$ExtClassLoader)實現的。它負責將(jre/lib/ext)或者由系統變量-Djava.ext.dir指定位置中的類庫加載到內存中。
3.系統類加載器(System):系統類加載器是由 Sun的AppClassLoader(sun.misc.Launcher$AppClassLoader)實現的。它負責將系統類路徑java-classpath或-Djava.class.path變量所指的目錄下的類庫加載到內存中。
它們之間使用了雙親委派機制,如下圖。簡單說就是,當類加載器有加載需求的時候,先請示他的父類使用父類的搜索路徑來加入,如果沒有找到的話,才使用自己的搜索路徑來來搜索類。
我們通過測試來看一下:
代碼:
package com.bjpowernode.cl;
public class Test {
/**
* Java類加載機制
*
* @param args
*/
public static void main(String[] args) {
System.out.println(ClassLoader.getSystemClassLoader());
System.out.println(ClassLoader.getSystemClassLoader().getParent());
System.out.println(ClassLoader.getSystemClassLoader().getParent()
.getParent());
}
}
結果是:
測試結果表明:System類加載器的父加載器是Ext加載器,Ext類加載器的父加載器時得到了null,就是說Ext類加載器本身的父類加載器被設定爲null,即用null來代表BootStrapLoader。
好,下面再來大致順一下Java類加載機制的工作方式:
當執行 java ***.class 的時候, java.exe 會幫助我們找到 JRE ,找到位於 JRE/bin/server中的 jvm.dll ,JVM是Java虛擬機,有了虛擬機之後再加載動態庫,激活 Java虛擬機。虛擬機器激活以後,會先做一些初始化的動作,比如說讀取系統參數等。一旦初始化動作完成之後,就會產生第一個類加載器―― Bootstrap Loader(啓動類加載器), Bootstrap Loader 是由 C++ 所撰寫而成,這個 Bootstrap Loader所做的初始工作中,除了一些基本的初始化動作之外,最重要的就是加載 Launcher.java 之中的 ExtClassLoader(擴展類加載器),並設定其 Parent 爲 null ,代表其父加載器爲 BootstrapLoader 。然後 Bootstrap Loader再要求加載 Launcher.java 之中的System,並設定其 Parent 爲之前產生的 ExtClassLoader實體。這兩個加載器都是以靜態類的形式存在的。
【Tomcat類加載器】
tomcat有自己的類加載機制,是在Java類加載機制上的一種擴展。如下圖:
每個項目都有自己的類加載器。
除了Java本身的三種類加載機制外,其他的:
1.Common:加載TOMCAT_HOME/common/*,對Tomcat和所有的web項目都起作用。
2.Catalina:加載TOMCAT_HOME/server/*,對Tomcat起作用,對其他Web項目不起作用。
3.Shared:加載TOMCAT_HOME/shared/*,它對所有的Web項目都起作用,對Tomcat不起作用。
4.Web App相關加載器:加載每個web項目,只對當前web項目起作用。