<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### Tomcat類加載器 Tomcat 的自定義類加載器`WebAppClassLoader`打破了雙親委托機制,它**首先自己嘗試去加載某個類,如果找不到再代理給父類加載器**,其目的是優先加載 Web 應用自己定義的類。具體實現就是重寫`ClassLoader`的兩個方法:`findClass`和`loadClass`。 ![](https://img.kancloud.cn/e0/9b/e09b5de9b96e4fb1be65fe5fce5c2aa9_569x485.png) #### findClass 方法 `org.apache.catalina.loader.WebappClassLoaderBase#findClass`;為了方便理解和閱讀,我去掉了一些細節: ~~~ public Class<?> findClass(String name) throws ClassNotFoundException { ... Class<?> clazz = null; try { //1. 先在 Web 應用目錄下查找類 clazz = findClassInternal(name); } catch (RuntimeException e) { throw e; } if (clazz == null) { try { //2. 如果在本地目錄沒有找到,交給父加載器去查找 clazz = super.findClass(name); } catch (RuntimeException e) { throw e; } //3. 如果父類也沒找到,拋出 ClassNotFoundException if (clazz == null) { throw new ClassNotFoundException(name); } return clazz; } ~~~ 1. 先在 Web 應用本地目錄下查找要加載的類。 2. 如果沒有找到,交給父加載器去查找,它的父加載器就是上面提到的系統類加載器`AppClassLoader`。 3. 如何父加載器也沒找到這個類,拋出`ClassNotFound`異常。 #### loadClass 方法 再來看 Tomcat 類加載器的`loadClass`方法的實現,同樣我也去掉了一些細節: ~~~ public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { Class<?> clazz = null; //1. 先在本地 cache 查找該類是否已經加載過 clazz = findLoadedClass0(name); if (clazz != null) { if (resolve) resolveClass(clazz); return clazz; } //2. 從系統類加載器的 cache 中查找是否加載過 clazz = findLoadedClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); return clazz; } // 3. 嘗試用 ExtClassLoader 類加載器類加載,為什么? ClassLoader javaseLoader = getJavaseClassLoader(); try { clazz = javaseLoader.loadClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); return clazz; } } catch (ClassNotFoundException e) { // Ignore } // 4. 嘗試在本地目錄搜索 class 并加載 try { clazz = findClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); return clazz; } } catch (ClassNotFoundException e) { // Ignore } // 5. 嘗試用系統類加載器 (也就是 AppClassLoader) 來加載 try { clazz = Class.forName(name, false, parent); if (clazz != null) { if (resolve) resolveClass(clazz); return clazz; } } catch (ClassNotFoundException e) { // Ignore } } //6. 上述過程都加載失敗,拋出異常 throw new ClassNotFoundException(name); } ~~~ 主要有六個步驟: 1. 先在本地 Cache 查找該類是否已經加載過,也就是說 Tomcat 的類加載器是否已經加載過這個類。 2. 如果 Tomcat 類加載器沒有加載過這個類,再看看系統類加載器是否加載過。 3. 如果都沒有,就讓**ExtClassLoader**去加載,這一步比較關鍵,目的**防止 Web 應用自己的類覆蓋 JRE 的核心類**。因為 Tomcat 需要打破雙親委托機制,假如 Web 應用里自定義了一個叫 Object 的類,如果先加載這個 Object 類,就會覆蓋 JRE 里面的那個 Object 類,這就是為什么 Tomcat 的類加載器會優先嘗試用`ExtClassLoader`去加載,因為`ExtClassLoader`會委托給`BootstrapClassLoader`去加載,`BootstrapClassLoader`發現自己已經加載了 Object 類,直接返回給 Tomcat 的類加載器,這樣 Tomcat 的類加載器就不會去加載 Web 應用下的 Object 類了,也就避免了覆蓋 JRE 核心類的問題。 4. 如果`ExtClassLoader`加載器加載失敗,也就是說`JRE`核心類中沒有這類,那么就在本地 Web 應用目錄下查找并加載。 5. 如果本地目錄下沒有這個類,說明不是 Web 應用自己定義的類,那么由系統類加載器去加載。這里請你注意,Web 應用是通過`Class.forName`調用交給系統類加載器的,因為`Class.forName`的默認加載器就是系統類加載器。 6. 如果上述加載過程全部失敗,拋出`ClassNotFound`異常。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看