類加載機制詳解:雙親委派模型與打破它的方式

在復雜的 Java 系統中,類加載是最基礎卻常被忽略的一環。理解 JVM 的類加載機制,特別是 雙親委派模型(Parent Delegation Model),是我們深入掌握熱部署、插件機制、ClassLoader 隔離、ClassNotFound 錯誤等問題的關鍵。

一、為什么你必須了解類加載機制?

想象幾個場景:

  • 使用 Tomcat 熱部署時類總是加載失敗?
  • SpringBoot 開啟 DevTools 后內存暴漲、類沖突?
  • 使用 SPI 擴展接口,卻加載不到自定義實現類?

所有這些問題背后,其實都是 類加載機制的問題。理解類是如何被加載、由誰加載、加載優先級如何決定,是中高級 Java 開發者邁向架構能力的必經之路。

二、JVM 中的類加載流程概覽

Java 類從被引用到可以使用,需要經過以下 生命周期階段:

加載(Loading) ? 驗證(Verification) ? 準備(Preparation) ? 解析(Resolution) ? 初始化(Initialization)

你可以簡單理解為:

JVM 讀取 .class ? 結構校驗 ? 為靜態變量分配內存 ? 解析符號引用 ? 執行 方法

三、什么是雙親委派模型?

定義

BootstrapClassLoader(引導類加載器)↑
ExtensionClassLoader(擴展類加載器)↑
AppClassLoader(應用類加載器)↑
Custom ClassLoader(自定義類加載器)

加載邏輯偽代碼

Class loadClass(String name) {// 已加載過,直接返回if (已加載類緩存中存在) return;// 委托父加載器加載if (parent != null) {try {return parent.loadClass(name);} catch (ClassNotFoundException e) {// 父類加載器找不到才嘗試自己加載}}// 自己加載return findClass(name);
}

目的:

  • 防止類重復加載
  • 保證Java核心類的安全性和唯一性
  • 實現類的隔離性

四、演示:雙親委派如何避免核心類被污染?

我們試圖編寫一個名為 java.lang.String 的類并將其放入 classpath,結果會怎樣?

package java.lang;
public class String {public String() {System.out.println("My Fake String Class");}
}

運行結果:

Error: Prohibited package name: java.lang

這是因為:

  • 核心類由 BootstrapClassLoader 先加載
  • 即使你的類也叫 java.lang.String,AppClassLoader 永遠加載不到它

五、為什么需要打破雙親委派模型?

盡管雙親委派是安全可靠的,但在實際開發中,它也存在一些限制:
典型場景:

場景說明
熱部署/類熱替換無法重新加載類,只能加載一次(類緩存)
模塊隔離(插件)插件類之間不能相互訪問
SPI(服務發現機制)接口在父加載器,實現在子加載器,無法反射加載
動態編譯/腳本執行引擎運行時生成類,不能由上層加載器訪問

六、打破雙親委派模型的方式

方法一:重寫 loadClass() 方法邏輯

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {// 先嘗試自己加載,不委托父類Class<?> c = findLoadedClass(name);if (c == null) {try {c = findClass(name); // 自己加載} catch (ClassNotFoundException e) {c = super.loadClass(name, resolve); // 找不到再委托父類}}return c;
}

注意:這樣可能會破壞類的唯一性,導致 ClassCastException、類沖突等問題。

方法二:使用多個自定義類加載器做模塊隔離

插件系統、腳本引擎常用此法:

ClassLoader pluginLoader1 = new MyClassLoader("pluginA/");
ClassLoader pluginLoader2 = new MyClassLoader("pluginB/");Class<?> clazz1 = pluginLoader1.loadClass("com.example.Plugin");
Class<?> clazz2 = pluginLoader2.loadClass("com.example.Plugin");System.out.println(clazz1 == clazz2); // false

不同插件類互相隔離,互不干擾。

七、雙親委派模型的常見陷阱

問題場景說明
類找不到(ClassNotFoundException)類存在但加載器層級錯誤
類轉換異常(ClassCastException)類名相同但加載器不同,導致不兼容
內存泄漏類加載器無法被卸載,常見于容器或熱部署場景

八、真實案例分析:Spring Boot DevTools

Spring Boot DevTools 實現類熱替換的核心,就是通過 自定義類加載器打破雙親委派模型。

  • 應用類由自定義 RestartClassLoader 加載
  • 每次修改后重新加載類
  • 保證熱更新不影響已運行類

九、類加載器在項目中的使用策略

場景建議做法
Web 容器部署避免將第三方 JAR 放入 shared/lib 中,易引發沖突
熱部署系統使用隔離 ClassLoader + SPI
插件系統每個插件一個加載器,父加載器只負責接口
工具類封裝使用當前線程類加載器(Thread.currentThread().getContextClassLoader())避免硬編碼

十、總結

雙親委派模型是 Java 類加載機制的基礎設計理念,保護了核心類的安全性與一致性。但在現代開發中,打破這個模型已經成為熱部署、插件化架構的必要手段。

開發者要做到:

  • 明確使用哪些加載器
  • 避免無意義的類重復加載
  • 善用隔離加載器做模塊隔離
  • 處理好類生命周期,防止泄漏

下一篇預告: 《JVM 調優實戰入門:從 GC 日志分析到參數調優》手把手教你理解 GC 日志、如何識別性能瓶頸并合理配置 JVM 參數!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82461.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82461.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82461.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android SDK 開發中的 AAR 與 JAR 區別詳解

在 Android SDK 開發中&#xff0c;構建項目時我們常常會看到生成兩個不同的文件&#xff1a;一個是 build/outputs/aar/*.aar&#xff0c;另一個是 build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar。很多初學者會疑惑&#xff1a;它們之間有什么區別&am…

服務器配置錯誤導致SSL/TLS出現安全漏洞,如何進行排查?

SSL/TLS 安全漏洞排查與修復指南 一、常見配置錯誤類型? 弱加密算法與密鑰問題? 使用弱密碼套件&#xff08;如DES、RC4&#xff09;或密鑰長度不足&#xff08;如RSA密鑰長度<2048位&#xff09;&#xff0c;導致加密強度不足。 密鑰管理不當&#xff08;如私鑰未加密存…

Day20打卡-奇異值SVD分解

今天學習非特征篩選的方法&#xff1a; 知識點回顧&#xff1a; 線性代數概念回顧&#xff08;可不掌握&#xff09;奇異值推導&#xff08;可不掌握&#xff09;奇異值的應用 特征降維&#xff1a;對高維數據減小計算量、可視化數據重構&#xff1a;比如重構信號、重構圖像&am…

temu采購自養號全流程解析:從賬號搭建到安全下單的技術閉環

temu 自養號采購下單技術是一個精細的過程&#xff0c;需要從多個方面進行考慮和操作&#xff0c;其核心在于通過技術手段模擬真實用戶行為&#xff0c;構建獨立、安全的賬號環境以確保賬號的安全性、真實性和采購下單的成功率。以下是對該技術的詳細解析 1. 賬號準備 手機號…

相機Camera日志分析之八:高通Camx HAL架構opencamera三級日志詳解及關鍵字

【關注我,后續持續新增專題博文,謝謝!!!】 上一篇我們講了:相機Camera日志分析之七:高通Camx HAL架構opencamera二級日志詳解及關鍵字 這一篇我們開始講: 相機Camera日志分析之八:高通Camx HAL架構opencamera三級日志詳解及關鍵字 目錄 【關注我,后續持續…

自定義類型-結構體(二)

結構體內存對齊 偏移量 指的是結構體中某個成員相對于結構體起始地址的字節距離 第一個成員的起始位置為0&#xff0c;一個字節表示一個單位 這里的數字表示的是該成員地址與結構體首地址之間的值 對齊規則 1.結構體第一個成員的第一個字節的偏移量為0 2.其余成員變量要…

【免費工具】圖吧工具箱2025.02正式版

DIY愛好者的必備工具 軟件截圖&#xff1a; —————【下 載 地 址】——————— 【本章單下載】&#xff1a;https://drive.uc.cn/s/f08aad37ddb14 【百款黑科技】&#xff1a;https://ucnygalh6wle.feishu.cn/wiki/HPQywvPc7iLZu1k0ODFcWMt2n0d?fromfrom_copylink …

DAX 權威指南1:DAX計算、表函數與計算上下文

參考《DAX 權威指南 第二版》 文章目錄 二、DAX簡介2.1 理解 DAX 計算2.2 計算列和度量值2.3 變量2.3.1 VAR簡介2.3.2 VAR的特性 2.4 DAX 錯誤處理2.4.1 DAX 錯誤類型2.4.1.1 轉換錯誤2.4.1.2 算術運算錯誤2.4.1.3 空值或 缺失值 2.4.2 使用IFERROR函數攔截錯誤2.4.2.1 安全地進…

【Linux系統】從零開始構建簡易 Shell:從輸入處理到命令執行的深度剖析

文章目錄 前言一、打印命令行提示符代碼功能概述 二、讀取鍵盤輸入的指令2.1 為什么不繼續使用scanf()而換成了fgets()&#xff1f;2.2 調試輸出的意義2.3 為什么需要去掉換行符&#xff1f; 三、指令切割補充知識&#xff1a; strtok 的函數原型 四、普通命令的執行代碼功能概…

湖倉一體架構在金融典型數據分析場景中的實踐

在數字經濟與金融科技深度融合的今天&#xff0c;數據已成為金融機構的核心戰略資產。然而&#xff0c;傳統數據架構面臨著三大困局&#xff0c;制約著金融機構數據價值的充分釋放。 一、需求驅動更多銀行數據分析場景 金融機構&#xff0c;特別是銀行業&#xff0c;面臨著雙重…

基于Llama3的開發應用(一):Llama模型的簡單部署

Llama模型的簡單部署 0 前言1 環境準備1.1 硬件環境1.2 軟件環境 2 Meta-Llama-3-8B-Instruct 模型簡介2.1 Instruct含義2.2 模型下載 3 簡單調用4 FastAPI 部署4.1 通過FastAPI簡單部署4.2 測試 5 使用 streamlit 構建簡易聊天界面6 總結 0 前言 本系列文章是基于Meta-Llama-…

模擬太陽系(C#編寫的maui跨平臺項目源碼)

源碼下載地址&#xff1a;https://download.csdn.net/download/wgxds/90789056 本資源為用C#編寫的maui跨平臺項目源碼&#xff0c;使用Visual Studio 2022開發環境&#xff0c;基于.net8.0框架&#xff0c;生成的程序為“模擬太陽系運行”。經測試&#xff0c;生成的程序可運行…

基于人工智能的個性化 MySQL 學習路徑推薦研究

基于人工智能的個性化 MySQL 學習路徑推薦研究 摘要: 隨著信息技術的飛速發展,數據庫在各行業應用廣泛,MySQL 作為主流數據庫之一,學習需求龐大。然而,不同學習者在知識水平、學習進度和目標上存在差異,傳統統一的學習路徑難以滿足個性化需求。本研究通過運用人工智能技…

OSPF綜合應用

? 要求&#xff1a; 1&#xff0c;R5為ISP&#xff0c;其上只能配置IP地址&#xff1b;R4作為企業邊界路由器&#xff0c; 出口公網地址需要通過PPP協議獲取&#xff0c;并進行chap認證 2&#xff0c;整個OSPF環境IP基于172.16.0.0/16劃分&#xff1b; 3&#xff0c;所有設備…

中國古代史1

朝代歌 三皇五帝始&#xff0c;堯舜禹相傳。 夏商與西周&#xff0c;東周分兩段。 春秋和戰國&#xff0c;一統秦兩漢。 三分魏蜀吳&#xff0c;二晉前后延。 南北朝并立&#xff0c;隋唐五代傳。 宋元明清后&#xff0c;皇朝至此完。 原始社會 元謀人&#xff0c;170萬年前…

ensp的華為小實驗

1.先進行子網劃分 2.進行接口的IP地址配置和ospf的簡易配置&#xff0c;先做到全網小通 3.進行ospf優化 對區域所有區域域間路由器進行一個匯總 對區域1進行優化 對區域2.3進行nssa設置 4.對ISP的路由進行協議配置 最后ping通5.5.5.5

華為OD機試真題——荒島求生(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳實現

2025 A卷 200分 題型 本專欄內全部題目均提供Java、python、JavaScript、C、C、GO六種語言的最佳實現方式&#xff1b; 并且每種語言均涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、3個測試用例以及綜合分析&#xff1b; 本文收錄于專欄&#xff1a;《2025華為OD真題目錄…

IOC和Bean

IOC IOC將對象的創建&#xff0c;依賴關系的管理和生命周期的控制從應用程序代碼中解耦出來了 IOC容器的依賴注入(DI) 在程序運行過程中動態的向某個對象中注入他所需要的其他對象 依賴注入是基于反射實現的 Spring IOC 容器使用的是Map&#xff08;concorrentMap&#xff…

vue3: pdf.js 2.16.105 using typescript

npm create vite vuepdfpreview //創建項目npm install vue-pdf-embed npm install vue3-pdfjs npm install pdfjs-dist2.16.105 <!--* |~~~~~~~|* | |* | |…

Java面試全棧解析:Spring Boot、Kafka與Redis實戰揭秘

《Java面試全棧解析&#xff1a;Spring Boot、Kafka與Redis實戰揭秘》 【面試現場】 面試官&#xff1a;&#xff08;推了推眼鏡&#xff09;小張&#xff0c;你簡歷里提到用Spring Boot開發過微服務系統&#xff0c;能說說自動配置的實現原理嗎&#xff1f; 程序員&#xff1…