Tomcat ClassLoader打破雙親委派源碼解析
java加載類
java加載類的時(shí)候需要使用類加載器,開發(fā)人員可以定制類的加載器,比如tomcat就擴(kuò)展了自己的類加載器。這篇文章結(jié)合代碼研究一下jdk類的加載器和tomcat的類加載
先上圖復(fù)習(xí)一下
來看一下jdk的ClassLoader的代碼
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // 本類加載器從緩存里面拿取已經(jīng)加載過的ClassLoader Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { // 父類為BootStrapClassLoader的classLoader 的parent變量為空 if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } .......... }
注意看一下核心代碼,實(shí)際上parent只要不為空就由parent來加載,因此當(dāng)類未加載的時(shí)候,總是由上級(jí)來優(yōu)先加載。
tomcat的類加載
首先來看一下tomcat的類加載器,tomcat寫了一個(gè)自己的類加載器,看下基類WebappClassLoaderBase的實(shí)現(xiàn)
@Override public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { ................ // 從緩存里面取,不影響加載順序,請(qǐng)著重忽略 clazz = findLoadedClass0(name); .......... clazz = findLoadedClass(name); ......... /** * The bootstrap class loader used to load the JavaSE classes. In some * implementations this class loader is always <code>null</code> and in * those cases {@link ClassLoader#getParent()} will be called recursively on * the system class loader and the last non-null result used. */ // 注意看注釋,javaseLoader是bootstrap加載的,所以javaseLoader是擴(kuò)展類加載器 ClassLoader javaseLoader = getJavaseClassLoader(); clazz = javaseLoader.loadClass(name); boolean delegateLoad = delegate || filter(name, true); // (2) Search local repositories if (log.isDebugEnabled()) { log.debug(" Searching local repositories"); } try { // 重寫了findClass方法,從項(xiàng)目中的lib和class里加載 clazz = findClass(name); if (clazz != null) { if (log.isDebugEnabled()) { log.debug(" Loading class from local repository"); } if (resolve) { resolveClass(clazz); } return clazz; } } catch (ClassNotFoundException e) { // Ignore } // (3) Delegate to parent unconditionally if (!delegateLoad) { if (log.isDebugEnabled()) { log.debug(" Delegating to parent classloader at end: " + parent); } try { // 繼承于SystemClassLoader該類,所以這個(gè)parent是SystemClassLoader, clazz = Class.forName(name, false, parent); if (clazz != null) { if (log.isDebugEnabled()) { log.debug(" Loading class from parent"); } if (resolve) { resolveClass(clazz); } return clazz; } } catch (ClassNotFoundException e) { // Ignore } } } throw new ClassNotFoundException(name); }
把順序相關(guān)外的代碼省略了,注意看注釋。
因此來梳理一下加載順序
1.找ext加載器,ext會(huì)優(yōu)先走BootStrap加載器,加載java核心類庫
2.ext加載不到就去走重寫的findClass,走web項(xiàng)目的lib包和class目錄,加載項(xiàng)目的class
3.重寫的findClass找不到,就去系統(tǒng)類加載器SystemClassLoader來加載。
tomcat為什么要重寫這個(gè)ClassLoader呢
1.最重要的就是做隔離性,不同的 web包引入不同的jar包版本,如果重寫類的加載順序,統(tǒng)一走SystemClassloader加載,那么只會(huì)加載一個(gè)類在內(nèi)存,另外一個(gè)版本的class永遠(yuǎn)也不會(huì)加載進(jìn)內(nèi)存。無法實(shí)現(xiàn)web項(xiàng)目的隔離
2.可以針對(duì)一個(gè)應(yīng)用進(jìn)行重新部署,一個(gè)應(yīng)用一個(gè)加載器,需要重新部署,就把這個(gè)classLoader加載的類重新加載就可以了
所以看起來打破雙親委派這種大名頭的知識(shí),看一下源碼就清晰了,養(yǎng)成閱讀源碼習(xí)慣就可以
以上就是Tomcat ClassLoader打破雙親委派源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Tomcat ClassLoader雙親委派的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解
這篇文章主要介紹了JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解,CountDownLatch 類可以設(shè)置一個(gè)計(jì)數(shù)器,然后通過 countDown 方法來進(jìn)行 減 1 的操作,使用 await 方法等待計(jì)數(shù)器不大于 0,然后繼續(xù)執(zhí)行 await 方法 之后的語句,需要的朋友可以參考下2024-01-01Servlet和Spring?MVC的區(qū)別及使用說明
這篇文章詳細(xì)介紹了Servlet和SpringMVC的基本概念、工作原理、功能對(duì)比和應(yīng)用場景,Servlet是JavaWeb開發(fā)的基礎(chǔ),而SpringMVC是一個(gè)基于Servlet的高級(jí)框架,提供了更強(qiáng)大的功能和易用性,文章通過定義、原理和示例代碼,幫助讀者理解這兩個(gè)技術(shù)的區(qū)別與聯(lián)系2025-01-01Java調(diào)用pyzbar解析base64二維碼過程解析
這篇文章主要介紹了Java調(diào)用pyzbar解析base64二維碼過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08SpringBoot實(shí)現(xiàn)文件在線預(yù)覽功能的全過程
我們開發(fā)業(yè)務(wù)系統(tǒng)的時(shí)候,經(jīng)常有那種文檔文件在線預(yù)覽的需求,下面這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)文件在線預(yù)覽功能的相關(guān)資料,需要的朋友可以參考下2021-11-11使用Criteria進(jìn)行分組求和、排序、模糊查詢的實(shí)例
這篇文章主要介紹了使用Criteria進(jìn)行分組求和、排序、模糊查詢的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03