tocmat類載入:正統的類載入

NO IMAGE

一個功能健全的Web伺服器,要解決如下幾個問題

部署在同一個伺服器上的兩個Web應用程式使用的Java類庫可以實現相互隔離。不能要求一個類庫在一個伺服器中只有一份,伺服器應當保證兩個應用程式的類庫可以互相獨立使用。
部署在同一個伺服器上的兩個Web應用程式所使用的Java類庫可以互相共享,如果Java類庫不能共享使用,虛擬機器的方法區很容易出現過度膨脹的風險,比如一臺伺服器上部署了10個使用Spring的程式。
伺服器需要儘可能保證自身安全不受部署的Web應用程式影響。伺服器所使用的類庫應該與應用程式使用的類庫互相獨立。
支援JSP的伺服器,大部分都需要支援HotSwap功能(熱交換功能)

tomcat的lib目錄結構

  Tomcat目錄結構中,有三組目錄(“/common/”,“/server/”和“shared/”)可以存放公用Java類庫,此外還有第四組Web應用程式自身的目錄“/WEB-INF/”,把java類庫放置在這些目錄中的含義分別是:

放置在common目錄中:類庫可被Tomcat和所有的Web應用程式共同使用。
放置在server目錄中:類庫可被Tomcat使用,但對所有的Web應用程式都不可見。
放置在shared目錄中:類庫可被所有的Web應用程式共同使用,但對Tomcat自己不可見。所有jar都合在lib包下
放置在/WebApp/WEB-INF目錄中:類庫僅僅可以被此Web應用程式使用,對Tomcat和其他Web應用程式都不可見。

注:tomcat 在6以後。廢棄了/common目錄,預設沒有shared目錄。

tomcat類載入模型

為了支援這套目錄結構,並對目錄裡面的類庫進行載入和隔離,Tomcat自定義了多個類載入器,這些類載入器按照經典的雙親委派模型來實現,如下圖所示 :
clipboard.png

Spring載入問題

Tomcat 載入器的實現清晰易懂,並且採用了官方推薦的“正統”的使用類載入器的方式。這時作者提一個問題:如果有 10 個 Web 應用程式都用到了spring的話,可以把Spring的jar包放到 common 或 shared 目錄下讓這些程式共享。Spring 的作用是管理每個web應用程式的bean,getBean時自然要能訪問到應用程式的類,而使用者的程式顯然是放在 /WebApp/WEB-INF 目錄中的(由 WebAppClassLoader 載入),那麼在 CommonClassLoader 或 SharedClassLoader 中的 Spring 容器如何去載入並不在其載入範圍的使用者程式(/WebApp/WEB-INF/)中的Class呢?

spring載入解答

spring根本不會去管自己被放在哪裡,它統統使用執行緒上下文載入器來載入類,而執行緒上下文載入器預設設定為了WebAppClassLoader,也就是說哪個WebApp應用呼叫了spring,spring就去取該應用自己的WebAppClassLoader來載入bean。