Servlet類裝載器
一.類裝載器
Java虛擬機器使用每一個類的第一件事情就是將類的位元組碼裝載進來,裝載類位元組碼是由類裝載器完成的。類裝載器首先將一個類轉換成一個.class檔案,然後讀取檔案的內容,.class檔案的內容是utf-8編碼的,轉換成Unicode編碼後裝載入Java虛擬機器,當一個類被載入後,Java虛擬機器將其編譯為可執行的程式碼儲存在記憶體中,索引資訊儲存進HashTable中,索引關鍵字為類的完整名稱,當Java虛擬機器要使用某個類時,直接在這個HashTable中找,找不到則載入。載入一個類實際上實在建立一個Class的物件,這個物件封裝的記憶體就是當前載入的類的位元組碼資料,有以下3種方式獲得Class物件:
- 類名.class
- 物件.getClass
- Class.forName("類名")
(1)類裝載器本身也是一個Java類,所以需要被其他類裝載器裝載。最頂層的裝載器為Bootstrap類裝載器,它是用特定與作業系統的原生代碼實現的,不用其餘的裝載器裝載,它負責載入Java核心包的類。Java核心包的類有2個類裝載器:ExtClassLoader和AppClassLoader。ExtClassLoader負責載入<JAVA_HOME>/jre/lib/ext目錄下的類,AppClassLoader負責載入應用程式的啟動執行類。
(2)一個類裝載器例項化時必須指定一個父裝載器,如果不指定。則以ClassLoader.getSystemClassLoader()方法返回的系統類裝載器為父裝載器,通常設定為AppClassLoader,是在第一次使用getSystemClassLoader()時設定的,呼叫發生在應用程式啟動的早期階段。可以通過java.system.class.loader來設定為其他類裝載器。ExtClassLoader是AppClassLoader的父級類裝載器,自身沒有父級類裝載器
(3)如果在A類物件中New了B類物件,則Java虛擬機器使用載入A類的載入器載入B類。如果使用Class.forName載入,可以指定類載入,如果沒有指定,則為載入當前類的載入器載入。
(4)每個執行的執行緒都有一個關聯的上下文類裝載器。可以使用Thread.setContextClassLoader()方法設定上下文類載入器,預設為其父執行緒的上下文類載入器。主執行緒的類載入器初始化為ClassLoader.getSystemClassLoader()返回的載入器。一樣採用委託模式載入,如果父載入器無法載入,則自己進行載入。
2.Tomcat中的類裝載器
類裝載器的父子關係圖如下:
- (1)Bootstrap是虛擬機器內嵌的裝載器和ExtClassLoader的總稱
- (2)System通常為AppClassLoader,載入CLASSPATH環境變數中的類
- (3)Commen載入<CATALINA_HOME>/commen/classes和<CATALINA_HOME>/commen/lib中的類,對Tomcat服務核心和每個Web應用程式都可見
- (4)Catalina負責<CATALINA_HOME>/server/classes和<CATALINA_HOME>/server/lib,只對Tomcat伺服器核心可見
- (5)Shared負責<CATALINA_HOME>/share/classes和<CATALINA_HOME>/share/lib,對所有Web程式可見,對Tomcat核心不可見
- (6)Webapp負責當前Web程式/Web-INF/classes中的.class檔案和/Web-INF/lib中的jar包,只對當前Web程式可見。