偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

秒懂雙親委派機制

開發(fā) 前端
由于用戶對程序動態(tài)性的追求,比如:代碼熱部署、代碼熱替換等功能,引入了OSGi(Open Service Gateway Initiative)。OSGi中的每一個模塊(稱為Bundle)。當程序升級或者更新時,可以只停用、重新安裝然后啟動程序的其中一部分,對企業(yè)來說這是一個非常誘人的功能。

前言

最近知識星球中,有位小伙伴問了我一個問題:JDBC為什么會破壞雙親委派機制?

這個問題挺有代表性的。

雙親委派機制是Java中非常重要的類加載機制,它保證了類加載的完整性和安全性,避免了類的重復加載。

這篇文章就跟大家一起聊聊,Java中類加載的雙親委派機制到底是怎么回事,有哪些破壞雙親委派機制的案例,為什么要破壞雙親委派機制,希望對你會有所幫助。

1 為什么要雙親委派機制?

我們的Java在運行之前,首先需要把Java代碼轉換成字節(jié)碼,即class文件。

然后JVM需要把字節(jié)碼通過一定的方式加載到內(nèi)存中的運行時數(shù)據(jù)區(qū)。

這種方式就是類加載器(ClassLoader)。

再通過加載、驗證、準備、解析、初始化這幾個步驟完成類加載過程,然后再由jvm執(zhí)行引擎的解釋器和JIT即時編譯器去將字節(jié)碼指令轉換為本地機器指令進行執(zhí)行。

我們在使用類加載器加載類的時候,會面臨下面幾個問題:

  • 如何保證類不會被重復加載?類重復加載會出現(xiàn)很多問題。
  • 類加載器是否允許用戶自定義?
  • 如果允許用戶自定義,如何保證類文件的安全性?
  • 如何保證加載的類的完整性?

為了解決上面的這一系列的問題,我們必須要引入某一套機制,這套機制就是:雙親委派機制。

2 什么是雙親委派機制?

接下來,我們看看什么是雙親委派機制。

雙親委派機制的基本思想是:當一個類加載器試圖加載某個類時,它會先委托給其父類加載器,如果父類加載器無法加載,再由當前類加載器自己進行加載。

這種層層委派的方式有助于保障類的唯一性,避免類的重復加載,并提高系統(tǒng)的安全性和穩(wěn)定性。

在Java中默認的類加載器有3層:

  1. 啟動類加載器(Bootstrap Class Loader):負責加載 %JAVA_HOME%/jre/lib 目錄下的核心Java類庫,比如:rt.jar、charsets.jar等。它是最頂層的類加載器,通常由C++編寫。
  2. 擴展類加載器(Extension Class Loader):負責加載Java的擴展庫,一般位于<JAVA_HOME>/lib/ext目錄下。
  3. 應用程序類加載器(Application Class Loader):也稱為系統(tǒng)類加載器,負責加載用戶類路徑(ClassPath)下的應用程序類。

用一張圖梳理一下,雙親委派機制中的3種類加載器的層次關系:

圖片圖片

但這樣不夠靈活,用戶沒法控制,加載自己想要的一些類。

于是,Java中引入了自定義類加載器。

創(chuàng)建一個新的類并繼承ClassLoader類,然后重寫findClass方法。

該方法主要是實現(xiàn)從那個路徑讀取 ar包或者.class文件,將讀取到的文件用字節(jié)數(shù)組來存儲,然后可以使用父類的defineClass來轉換成字節(jié)碼。

如果想破壞雙親委派的話,就重寫loadClass方法,否則不用重寫。

類加載器的層次關系改成:

圖片圖片

雙親委派機制流程圖如下:

圖片圖片

具體流程大概是這樣的:

  • 需要加載某個類時,先檢查自定義類加載器是否加載過,如果已經(jīng)加載過,則直接返回。
  • 如果自定義類加載器沒有加載過,則檢查應用程序類加載器是否加載過,如果已經(jīng)加載過,則直接返回。
  • 如果應用程序類加載器沒有加載過,則檢查擴展類加載器是否加載過,如果已經(jīng)加載過,則直接返回。
  • 如果擴展類加載器沒有加載過,則檢查啟動類加載器是否加載過,如果已經(jīng)加載過,則直接返回。
  • 如果啟動類加載器沒有加載過,則判斷當前類加載器能否加載這個類,如果能加載,則加載該類,然后返回。
  • 如果啟動類加載器不能加載該類,則交給擴展類加載器。擴展類加載器判斷能否加載這個類,如果能加載,則加載該類,然后返回。
  • 如果擴展類加載器不能加載該類,則交給應用程序類加載器。應用程序類加載器判斷能否加載這個類,如果能加載,則加載該類,然后返回。
  • 如果應用程序類加載器不能加載該類,則交給自定義類加載器。自定義類加載器判斷能否加載這個類,如果能加載,則加載該類,然后返回。
  • 如果自定義類加載器,也無法加載這個類,則直接拋ClassNotFoundException異常。

這樣做的好處是:

  • 保證類不會重復加載。加載類的過程中,會向上問一下是否加載過,如果已經(jīng)加載了,則不會再加載,這樣可以保證一個類只會被加載一次。
  • 保證類的安全性。核心的類已經(jīng)被啟動類加載器加載了,后面即使有人篡改了該類,也不會再加載了,防止了一些有危害的代碼的植入。

3 破壞雙親委派機制的場景

既然Java中引入了雙親委派機制,為什么要破壞它呢?

答:因為它有一些缺點。

下面給大家列舉一下,破壞雙親委派機制最常見的場景。

3.1 JNDI

JNDI是Java中的標準服務,它的代碼由啟動類加載器去加載。

但JNDI要對資源進行集中管理和查找,它需要調(diào)用由獨立廠商在應用程序的ClassPath下的實現(xiàn)了JNDI接口的代碼,但啟動類加載器不可能“認識”這些外部代碼。

為了解決這個問題,Java后來引入了線程上下文類加載器(Thread Context ClassLoader)。

這個類加載器可以通過java.lang.Thread類的setContextClassLoader()方法進行設置。

如果創(chuàng)建線程時沒有設置,他將會從父線程中繼承一個,如果在應用程序的全局范圍內(nèi)都沒有設置過的話,那這個類加載器默認就是應用程序類加載器。

有了線程上下文加載器,JNDI服務就可以使用它去加載所需要的SPI代碼,也就是父類加載器請求子類加載器去完成類加載的動作,這樣就打破了雙親委派機制。

3.2 JDBC

原生的JDBC中Driver驅(qū)動本身只是一個接口,并沒有具體的實現(xiàn),具體的實現(xiàn)是由不同數(shù)據(jù)庫類型去實現(xiàn)的。

例如,MySQL的mysql-connector.jar中的Driver類具體實現(xiàn)的。

原生的JDBC中的類是放在rt.jar包,是由啟動類加載器進行類加載的。

在JDBC中需要動態(tài)去加載不同數(shù)據(jù)庫類型的Driver實現(xiàn)類,而mysql-connector.jar中的Driver實現(xiàn)類是用戶自己寫的代碼,啟動類加載器肯定是不能加載的,那就需要由應用程序啟動類去進行類加載。

為了解決這個問題,也可以使用線程上下文類加載器(Thread Context ClassLoader)。

3.3  Tomcat容器

Tomcat是Servlet容器,它負責加載Servlet相關的jar包。

此外,Tomcat本身也是Java程序,也需要加載自身的類和一些依賴jar包。

這樣就會帶來下面的問題:

  1. 一個Tomcat容器下面,可以部署多個基于Servlet的Web應用,但如果這些Web應用下有同名的Servlet類,又不能產(chǎn)生沖突,需要相互獨立加載和運行才行。
  2. 但如果多個Web應用,使用了相同的依賴,比如:SpringBoot、Mybatis等。這些依賴包所涉及的文件非常多,如果全部都獨立,可能會導致JVM內(nèi)存不足。也就是說,有些公共的依賴包,最好能夠只加載一次。
  3. 我們還需要將Tomcat本身的類,跟Web應用的類隔離開。

這些原因?qū)е?,Tomcat沒有辦法使用傳統(tǒng)的雙親委派機制加載類了。

那么,Tomcat加載類的機制是怎么樣的?

圖片圖片

  • CommonClassLoader:是Tomcat最基本的類加載器,它加載的類可以被Tomcat容器和Web應用訪問。
  • CatalinaClassLoader:是Tomcat容器私有的類加載器,加載類對于Web應用不可見。
  • SharedClassLoader:各個Web應用共享的類加載器,加載的類對于所有Web應用可見,但是對于Tomcat容器不可見。
  • WebAppClassLoader:各個Web應用私有的類加載器,加載類只對當前Web應用可見。比如不同war包應用引入了不同的Spring版本,這樣能加載各自的Spring版本,相互隔離。

3.4 熱部署

由于用戶對程序動態(tài)性的追求,比如:代碼熱部署、代碼熱替換等功能,引入了OSGi(Open Service Gateway Initiative)。

OSGi中的每一個模塊(稱為Bundle)。

當程序升級或者更新時,可以只停用、重新安裝然后啟動程序的其中一部分,對企業(yè)來說這是一個非常誘人的功能。

OSGi的Bundle類加載器之間只有規(guī)則,沒有固定的委派關系。

各個Bundle加載器是平級關系。

不是雙親委派關系。

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2023-10-30 01:02:56

Java類類加載器雙親委派

2023-08-04 08:53:42

2021-03-01 08:54:39

開發(fā)雙親委派

2023-02-03 07:24:49

雙親委派模型

2025-07-01 07:41:37

Java類加載器雙親委派

2025-05-19 00:00:55

2023-12-06 12:11:43

類加載器雙親委派模型

2018-02-07 08:32:42

2024-07-05 09:31:37

2025-04-07 04:25:00

JDBCAPI加載器

2024-06-06 08:50:43

2024-03-27 09:15:27

2020-04-20 10:33:56

戴爾

2018-04-26 08:40:33

線性回歸算法機器學習

2018-05-11 09:29:18

云計算火鍋IaaS

2024-12-04 09:01:55

引導類加載器C++

2024-12-06 11:23:36

Context容器Tomcat

2019-11-27 14:56:35

關機電腦硬件

2022-06-19 22:54:08

TypeScript泛型工具

2022-10-11 23:18:28

散列表函數(shù)數(shù)組
點贊
收藏

51CTO技術棧公眾號