Tomacat類加載機制

Tomacat類加載機制

tomcat中提供了多種類加載器,以便web應用程序部署到tomcat中可以共享類加載器也可以加載各自應用中WEB-INF的lib目錄下面導入的類。在Tomcat啓動的時候就會初始化它當中的類加載器。

在Tomcat的目錄結構中有/common/*   /server/*  /shared/*三個目錄結構來存放tomcat應用程序能用到的類庫,以及/WEB-INF/*應用程序自身用到的類庫。下圖是tomcat中類加載器示意圖,紅色框選的是區別於JVM的類加載器,根據名字用來加載對應目錄的類庫

 

/common/* :類庫可以被Tomcat和所有的web應用程序使用   ommonClassLoader

/server/* :被Tomcat使用,對於web程序不可見   CatalinaClassLoader

/shared/* :被web程序使用,對Tomcat不可見   SharedClassLoader

/WEB-INF/* 僅當前web程序可見類庫    WebAppClassLoad

從示意圖可以看出,common類加載器加載的類可以被CatalinaClassLoader和SharedClassLoader使用,而CatalinaClassLoader和SharedClassLoader加載的類與對方隔離,WebAppClassLoad和JsperClassLoader一般會有多個實例且各個實例之間互相隔離,每一個web應用都會對應一個WebApp類加載器,每一個Jsp對應一個Jsp類加載器

 但是在Tomcat的6.x版本中,把/common/*   /server/*  /shared/*三個目錄合併爲一個lib目錄

並且在Tomcat\apache-tomcat-8.5.32\conf\catalina.properties中只配置了common類加載器,CatalinaClassLoader和SharedClassLoader爲空,看到用common類加載器加載了lib中的全部類庫,當然可以設置server.loader和shared.loader重新啓用Tomcat5.x

 Tomcat類加載過程

(1)在Tomcat啓動時,會創建一系列的類加載器,在其主類Bootstrap的初始化過程中,會先初始化classloader,然後將其綁定到Thread中。 

(2)其中initClassLoaders方法,會根據catalina.properties的配置,創建相應的classloader。由於默認只配置了common.loader屬性,所以其中只會創建一個出來

(3)然後,當一個應用啓動的時候,會爲其創建對應的WebappClassLoader。此時會將commonClassLoader設置爲其parent

(4)在加載時,與java雙親委託機制不同,默認是子優先,也就是先用子加載器加載但是保證Java的基礎類不允許其重新加載,以及servlet-api也不允許重新加載。

 拋出的問題

這裏拋出一個問題,如果有10個web應用程序都是用Spring來進行組織個管理的,可以把 Spring放到Common或shared目錄下讓這些程序共享。spring要對用戶程序進行管理,當然也要能訪問到程序自己的類庫,就是方法WEB-INF/lib下面的類庫,那麼被common類加載或者shared類加載器加載的spring如何訪問那些類庫呢?或者說如何調用WebApp類加載器呢?

當然就是前片所說的使用線程上下文類加載器,當我們在spring的配置文件中通過類來創建對象,spring都是使用線程上下文類加載器來加載了,默認設置爲WebAppClassLoader,所以當在web應用程序內,spring通過線程上下文類加載器使用WebAppClassLoader來加載bean

 

發佈了152 篇原創文章 · 獲贊 18 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章