Java(5)-雙親委派機制

marigo發表於2024-05-04

如何理解雙親委派機制

雙親委派機制是Java中類載入器載入類的一種方法,可以想象一個大家庭中的孩子想要一本書來閱讀:
在這個家庭中,孩子會先向他的父親(子類載入器)要這本書,如果沒有這本書,他的父親就會去向孩子的祖父(父類載入器)要這本書。這個過程會一直持續,直到到達家族中的最高輩分,通常是引導類載入器(Bootstrap ClassLoader)
如果在這一連串的查詢中,任何一個家長找到了這本書,他就會將書傳給請求的孩子。這樣做的好處是,確保了所有人都在使用同一版本的書籍,避免了可能出現的混亂或不一致。
如果整個家族中沒有人有這本書,那麼最初被問到的父親(子類載入器)可能會決定去書店(檔案系統或其他來源)買一本。一旦買到書,他會按照同樣的路徑,把書傳遞回去給孩子。
這種機制確保了Java環境中類的載入是有序的,可以避免類的重複載入,並且有助於保持安全和整潔的程式碼環境。它也幫助系統維護者更好地控制類的版本和提供統一的行為
我們再用比較書面的表達重新理解雙親委派機制的流程:
1. 快取查詢:當一個類載入請求發生時,類載入器首先檢查其內部快取,看是否已經載入過請求的類。如果找到了,就直接返回該類,不再進行任何載入。
2. 雙親委派:如果在自己的快取中沒有找到該類,類載入器會遵循雙親委派模型,請求其父類載入器進行載入。這個過程會一直向上遞迴,直至最頂層的類載入器(通常是引導類載入器)。[類載入序列:自定義類載入器 -> 應用程式類載入器 -> 擴充套件類載入器 -> 啟動類載入器]
3. 自行載入:如果所有的父類載入器都不能載入該類(即它們的快取中也沒有這個類,並且它們嘗試從自己的資源中載入失敗),控制權最終會回到發起請求的類載入器。這時,如果該類載入器有權從檔案系統或其他資源中載入類,它將嘗試自行載入這個類。
4. 快取結果:無論類是由哪個類載入器載入的,一旦載入成功,該類的定義會被儲存在相應載入器的快取中,以便未來可以快速訪問。

雙親委派機制用了什麼設計模式

GPT告訴我的,可能有誤。
雙親委派機制在Java的類載入器中使用了代理模式(Proxy Pattern)。這種模式涉及到使用一個代理物件來控制對另一個物件的訪問。在雙親委派模型中,每個類載入器(子類載入器)在嘗試載入類時,首先會代理請求給其父類載入器,這種代理繼續向上直至達到最頂層的類載入器,通常是引導類載入器。
這種設計允許系統保持類載入的順序和層次,同時確保每個類只被載入一次,防止重複載入同一個類。透過這種代理方式,Java的類載入機制能夠提供一個更加安全和可控的環境,因為最上層的類載入器控制了所有下層載入器的載入行為,保證了系統類的優先載入和應用類的隔離。這樣不僅有利於安全性,也有助於避免類的版本衝突。

為什麼要用雙親委派模型

  1. 避免類的重複載入: 透過委派給⽗類載入器載入類,可以確保同⼀個類不會被多個類載入器重複載入。這有助於節省記憶體資源,並確保類之間的互操作性。
  2. 保護Java核心類庫:由於雙親委派機制的存在,使用者自定義的類載入器無法直接載入java核心類庫,有助於保護核心類庫的安全性,防止惡意程式碼篡改或者破壞。
  3. 維護類載入器的層次結構:雙親委派模式使得各級類載入器可以按照⼀定的層次結構來組織和管理。這有助於降低類載入器的複雜性,簡化類載入過程。

雙親委派機制的缺點

  1. 類版本衝突:當不同的庫或框架需要不同版本的同一個類時,雙親委派模型可能會導致問題。由於類載入器首先會嘗試從父載入器那裡載入類,因此可能最終使用的是一個不符合當前需要的版本。這在大型應用或多模組應用中尤其成問題,可能需要精細地管理類路徑和載入器的結構。
  2. 載入器行為的僵化:雙親委派模型在設計上是僵化的,因為它強制要求所有的載入請求必須遵循固定的父到子的順序。這限制了更靈活的載入策略,比如動態載入或熱替換類,這些策略在某些應用開發中可能非常有用。
  3. 除錯和故障排查難度增加:當類載入問題發生時,由於類載入過程涉及多個載入器和可能的遞迴委派,這使得除錯和故障排查變得更加複雜。開發者需要清晰地理解各個載入器的層級和作用,才能有效地定位和解決問題。
  4. 靈活性降低:在某些情況下,開發者可能需要繞過標準的類載入機制來滿足特定的需求,如在執行時動態地替換或修改類的行為。由於雙親委派模型的嚴格性,這些需求可能難以實現,或者需要採用更復雜的解決方案。
  5. 影響外掛化架構:在外掛化的應用框架中,雙親委派模型可能會阻礙外掛之間的類隔離。例如,如果兩個外掛依賴於不同版本的同一個庫,標準的雙親委派模型可能不足以解決這種隔離需求,需要額外的技術手段來處理。

如何打破雙親委派模型

類的載入方式預設都是雙親委派。
如果我們有一個類想透過自定義的類載入器來載入,而不是透過系統預設的類載入器,就需要打破雙親委派機制。
雙親委派的機制是ClassLoader中的loadClass方法實現的,打破雙親委派,其實就是重寫這個方法,來用我們自己的方式來實現即可。
面試必備:什麼時候要打破雙親委派機制?什麼是雙親委派? (圖解+秒懂+史上最全) - 瘋狂創客圈 - 部落格園

相關文章