最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java如何加載外部Jar的類并通過反射調(diào)用類的方法

 更新時(shí)間:2024年06月17日 09:24:33   作者:編程經(jīng)驗(yàn)分享  
這篇文章主要介紹了Java如何加載外部Jar的類并通過反射調(diào)用類的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

問題

工作中遇到一個(gè)需求,客戶端將第三方的 jar 包上傳到服務(wù)器中,系統(tǒng)需要解析出上傳的 jar 中所有類以及類下的方法(方法名,方法輸入?yún)?shù)類型,方法返回值類型),并將這些類以及方法提供給配置人員選擇,由配置人員自由配置需要用到的方法。

類加載器

Java 虛擬機(jī)在加載類文件時(shí),默認(rèn)情況下使用自帶的三個(gè)類加載器

  • BootstrapClassLoader:加載 %JRE_HOME%\jre\lib 下的 jar 和 class
  • ExtentionClassLoader:加載 %JRE_HOME%\jre\lib\ext 下的 jar 和 class
  • AppClassLoader:加載當(dāng)前應(yīng)用路徑下的 class

在 JDK 1.8 的 rt.jar 中,Launcher 類里定義了這三個(gè)類加載器

可以從源碼中看到,三個(gè)加載器分別指定了不同的加載路徑來加載類

  • BootstrapClassLoader
private static String bootClassPath = System.getProperty("sun.boot.class.path");
  • ExtentionClassLoader
System.getProperty("java.class.path")
  • AppClassLoader
System.getProperty("java.ext.dirs")

三個(gè)加載器通過雙親委派機(jī)制來加載類文件,每個(gè)加載器都只負(fù)責(zé)加載自己負(fù)責(zé)的加載路徑,顯然,如果要自定義加載路徑,從而實(shí)現(xiàn)加載外部 jar 包,就必須自定義加載器來實(shí)現(xiàn)。

在 JDK 1.8 中,可以看到 AppClassLoader 和 ExtClassLoader 都是繼承 URLClassLoader 來實(shí)現(xiàn)的。

若要加載外部的 jar 包,只需拿到外部 jar 包的 URL 路徑,用 URLClassLoader 便可以加載。

獲取外部 jar 包中的類以及方法

public class JarUtils {
    /**
     * 這些默認(rèn)方法不打印
     */
    private static List<String> DEFAULT_METHODS = Arrays.asList("wait", "equals", "notify", "notifyAll", "toString", "hashCode" , "getClass");

    public static void parseJar(File file) throws Exception {
        URL url = file.toURI().toURL();
        try (URLClassLoader myClassLoader = new URLClassLoader(new URL[]{url}, Thread.currentThread().getContextClassLoader())) {
            //通過jarFile和JarEntry得到所有的類
            JarFile jar = new JarFile(file);
            //返回zip文件條目的枚舉
            Enumeration<JarEntry> enumFiles = jar.entries();
            JarEntry entry;
            //測(cè)試此枚舉是否包含更多的元素
            while (enumFiles.hasMoreElements()) {
                entry = enumFiles.nextElement();
                if (entry.getName().indexOf("META-INF") < 0) {
                    String classFullName = entry.getName();
                    if (classFullName.endsWith(".class")) {
                        //去掉后綴.class
                        String className = classFullName.substring(0, classFullName.length() - 6)
                                .replace("/", "."); //類名
                        Class<?> myclass = myClassLoader.loadClass(className);

                        System.out.println(String.format("類名:%s", className));

                        //得到類中包含的屬性
                        Method[] methods = myclass.getMethods();
                        for (Method method : methods) {
                            String methodName = method.getName();
                            if (DEFAULT_METHODS.contains(methodName)) {
                                continue;
                            }

                            //方法名
                            System.out.print(String.format("方法名:%s; ", methodName));

                            Class<?>[] parameterTypes = method.getParameterTypes(); //方法參數(shù)類型

                            System.out.print(String.format("方法參數(shù)類型:%s; ", Arrays.stream(parameterTypes)
                                    .map(Class::getSimpleName).collect(joining(","))));

                            System.out.println(String.format("方法返回類型:%s; ", method.getReturnType().getSimpleName())); //方法返回值類型
                        }
                        System.out.println("***************************");
                    }
                }
            }
        } catch (IOException e) {
            throw e;
        }
    }

}

調(diào)用外部 jar 包中的方法

public class JarUtils {

    public static void executeMethod(File f, String className, String methodName, Class[] classes, Object[] objects) {
        //通過URLClassLoader加載外部jar
        try (URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{f.toURI().toURL()})) {
            //獲取外部jar里面的具體類對(duì)象
            Class<?> targetClass = urlClassLoader.loadClass(className);
            //創(chuàng)建對(duì)象實(shí)例
            Object instance = targetClass.newInstance();
            //獲取實(shí)例當(dāng)中的方法名為show,參數(shù)只有一個(gè)且類型為string的public方法
            Method method = targetClass.getMethod(methodName, classes);
            //傳入實(shí)例以及方法參數(shù)信息執(zhí)行這個(gè)方法
            Object returnObj = method.invoke(instance, objects);
            System.out.println(returnObj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot配置嵌入式servlet容器的方法

    springboot配置嵌入式servlet容器的方法

    這篇文章主要介紹了springboot配置嵌入式servlet容器的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • springboot實(shí)現(xiàn)調(diào)用百度ocr實(shí)現(xiàn)身份識(shí)別+二要素校驗(yàn)功能

    springboot實(shí)現(xiàn)調(diào)用百度ocr實(shí)現(xiàn)身份識(shí)別+二要素校驗(yàn)功能

    本文介紹了如何使用Spring Boot調(diào)用百度OCR服務(wù)進(jìn)行身份識(shí)別,并通過二要素校驗(yàn)確保信息準(zhǔn)確性,感興趣的朋友一起看看吧
    2025-03-03
  • Java排序算法總結(jié)之堆排序

    Java排序算法總結(jié)之堆排序

    這篇文章主要介紹了Java排序算法總結(jié)之堆排序,詳細(xì)分析了堆排序的原理與java實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-05-05
  • 在idea中g(shù)it pull失敗的解決方案

    在idea中g(shù)it pull失敗的解決方案

    在遇到Git Pull失敗時(shí),首先使用IDEA的git-revert功能進(jìn)行還原,然后檢查并解決分支沖突,最后重新執(zhí)行Git Pull確保所有文件是最新的,注意,在操作過程中確保網(wǎng)絡(luò)連接正常,并且每步操作后都要執(zhí)行Git Pull來更新數(shù)據(jù)
    2024-10-10
  • 在mybatis 中使用if else 進(jìn)行判斷的操作

    在mybatis 中使用if else 進(jìn)行判斷的操作

    這篇文章主要介紹了在mybatis 中使用if else 進(jìn)行判斷的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • springboot上傳文件并返回url過程

    springboot上傳文件并返回url過程

    這篇文章主要介紹了springboot上傳文件并返回url過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(37)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(37)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • Spring中的BeanFactory類入門到精通

    Spring中的BeanFactory類入門到精通

    BeanFactory是Spring框架的IoC容器接口,提供Bean的生命周期管理、依賴注入和配置元數(shù)據(jù),它支持懶加載策略,并通過實(shí)現(xiàn)類如DefaultListableBeanFactory來完成具體的Bean創(chuàng)建和依賴注入,本文介紹Spring中的BeanFactory類,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • Java?Servlet異步請(qǐng)求開啟的簡(jiǎn)單步驟

    Java?Servlet異步請(qǐng)求開啟的簡(jiǎn)單步驟

    Java servlet是大家公認(rèn)的服務(wù)器端web技術(shù)的標(biāo)準(zhǔn),包括jsp,jsf,和大量的web框架,soap,RESTful web service api,還有新聞供應(yīng),下面這篇文章主要給大家介紹了關(guān)于Java?Servlet異步請(qǐng)求開啟的簡(jiǎn)單步驟,需要的朋友可以參考下
    2022-02-02
  • java基礎(chǔ)javeSE程序邏輯控制語法

    java基礎(chǔ)javeSE程序邏輯控制語法

    主要講解Java中程序的邏輯控制語句包括 Java中的輸入輸出方式 順序結(jié)構(gòu)循環(huán)結(jié)構(gòu)等,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09

最新評(píng)論

贵德县| 和硕县| 宜兰县| 休宁县| 社会| 班戈县| 光泽县| 衢州市| 大连市| 遵义市| 侯马市| 平舆县| 永宁县| 弋阳县| 永平县| 静安区| 莆田市| 建宁县| 淮安市| 塘沽区| 门源| 闽清县| 平和县| 泾阳县| 盐亭县| 资源县| 安溪县| 兰坪| 沁源县| 聂荣县| 东平县| 天津市| 赫章县| 衡山县| 乌兰县| 辉县市| 永登县| 竹山县| 黔西| 建昌县| 岑溪市|