中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

java~通(tong)過ClassLoader動(dong)態加載~tomcat模型

在(zai)進行非WEB項(xiang)目(Springboot)進行開發時(shi),使用(yong)(yong)classLoader進行動態加載jar,并使用(yong)(yong)接口進行強類型轉換(huan)是沒(mei)有問(wen)題的(de),它(ta)們使用(yong)(yong)JVM下(xia)的(de)URLClassLoader進行實現,而在(zai)基(ji)于(yu)tomcat的(de)容(rong)器里使用(yong)(yong)它(ta)時(shi),出現了類型無法找到(dao)的(de)問(wen)題,原(yuan)因(yin)如下(xia):

tomcat有個叫webApp的加載器它是先加載WEB-INF/classes后在加載WEB-INF/lib,但它的父加載器是它的common加載器,comon的父加載器是system加載器(和JVM的應用程序加載器功能差不多,不過指定了其他tomcat目錄下的加載,大家可以看看官網上的英文文檔),但是源碼中這個加載器是URLClassLoader的子類,而URLClassLoader默認父加載tomcat下是它的system加載器這么設計和tomcat的配置有關,默認為無為false,會直接委托給tomcat的system加載器加載system委托最頂層的Bootstrap加載器(差不多是JVM里起始加載器和擴展加載器的合并),但不管怎么樣,項目在tomcat下自定義的或者URLClassLoader加載默認父加載器都不會是tomcat的webApp加載器而是system加載器,或者自定義的加載器或URLClassLoader和tomcat的webApp加載器沒有上下關系,所以動態創建類時設計到其他類時肯定會報CNF異常。

參考



Tomcat ClassLoader

1

解決方法

一 解決思路就是先(xian)獲(huo)取(qu)當(dang)前類的(de)(de)Class,然(ran)后獲(huo)取(qu)當(dang)前類的(de)(de)加(jia)(jia)(jia)載(zai)器(qi)(qi),在自定義的(de)(de)加(jia)(jia)(jia)載(zai)器(qi)(qi)或(huo)(huo)者(zhe)URLClassLoader加(jia)(jia)(jia)載(zai)器(qi)(qi)創建時指定為它們(men)(men)的(de)(de)父(fu)加(jia)(jia)(jia)載(zai)器(qi)(qi),這樣問題就會(hui)游(you)刃而解了,可能平常(chang)我們(men)(men)測試寫個簡單的(de)(de)例子沒遇到(dao)(dao)這個問題,因為我們(men)(men)那時的(de)(de)URLClassLoader或(huo)(huo)者(zhe)自定義的(de)(de)加(jia)(jia)(jia)載(zai)器(qi)(qi)的(de)(de)父(fu)加(jia)(jia)(jia)載(zai)器(qi)(qi)都是JVM的(de)(de)第三次(ci)加(jia)(jia)(jia)載(zai)器(qi)(qi)即應用程序加(jia)(jia)(jia)載(zai),它是專(zhuan)門加(jia)(jia)(jia)載(zai)classpath下邊(bian)的(de)(de)或(huo)(huo)者(zhe)指定的(de)(de)類或(huo)(huo)者(zhe)jar的(de)(de),依照(zhao)雙親委托模(mo)型,肯(ken)定會(hui)找到(dao)(dao)引(yin)入路徑的(de)(de)那個類或(huo)(huo)者(zhe)jar的(de)(de)。

二 使用Class.forName()的方式(shi)來動(dong)態加載(zai)指(zhi)定的類(lei),就(jiu)不(bu)(bu)會存在這(zhe)(zhe)個問題,因為(wei)這(zhe)(zhe)種(zhong)方式(shi)一方面是能初始化類(lei)的靜態東西,再就(jiu)是重(zhong)要一點(dian),就(jiu)是采用的加載(zai)當前所在類(lei)的加載(zai)器(qi)來加載(zai)你指(zhi)定的類(lei),這(zhe)(zhe)樣你在tomcat下那就(jiu)是它的webApp加載(zai)器(qi)啊,肯定不(bu)(bu)再出(chu)現這(zhe)(zhe)個問題,可能直接就(jiu)從(cong)緩(huan)存里找到了。

動態加載代碼

             URL url = new URL(packageUrl);
            // IDEA調試時與java運行時的ClassLoader是不同的,所以需要使用當前環境下的ClassLoader
            ClassLoader loader = new URLClassLoader(new URL[]{url}, clazz.getClassLoader()) {
                @Override
                public Class<?> loadClass(String name) throws ClassNotFoundException {
                    try {
                        String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                        InputStream is = getClass().getResourceAsStream(fileName);
                        if (is == null) {
                            return super.loadClass(name);
                        }
                        byte[] b = new byte[is.available()];
                        is.read(b);
                        return defineClass(name, b, 0, b.length);

                    } catch (IOException e) {
                        e.printStackTrace();
                        throw new ClassNotFoundException(name);
                    }
                }
            };
posted @ 2020-11-27 09:53  張占嶺  閱讀(535)  評論(0)    收藏  舉報