欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java如何加載外部Jar的類并通過反射調用類的方法

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

問題

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

類加載器

Java 虛擬機在加載類文件時,默認情況下使用自帶的三個類加載器

  • BootstrapClassLoader:加載 %JRE_HOME%\jre\lib 下的 jar 和 class
  • ExtentionClassLoader:加載 %JRE_HOME%\jre\lib\ext 下的 jar 和 class
  • AppClassLoader:加載當前應用路徑下的 class

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

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

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

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

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

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

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

public class JarUtils {
    /**
     * 這些默認方法不打印
     */
    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;
            //測試此枚舉是否包含更多的元素
            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;
        }
    }

}

調用外部 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里面的具體類對象
            Class<?> targetClass = urlClassLoader.loadClass(className);
            //創(chuàng)建對象實例
            Object instance = targetClass.newInstance();
            //獲取實例當中的方法名為show,參數(shù)只有一個且類型為string的public方法
            Method method = targetClass.getMethod(methodName, classes);
            //傳入實例以及方法參數(shù)信息執(zhí)行這個方法
            Object returnObj = method.invoke(instance, objects);
            System.out.println(returnObj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

總結

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

相關文章

  • SpringBoot中的@FeignClient注解使用

    SpringBoot中的@FeignClient注解使用

    文章主要介紹了SpringCloud中的@FeignClient注解的使用及其參數(shù)詳解,包括value/name、url、path、configuration、fallback/fallbackFactory、contextId等,通過@FeignClient注解,可以方便地聲明一個REST客戶端,并定義與目標服務通信的接口
    2024-11-11
  • Maven實現(xiàn)項目構建工具

    Maven實現(xiàn)項目構建工具

    本文主要介紹了Maven實現(xiàn)項目構建工具,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • Java方法重載實現(xiàn)原理及代碼實例

    Java方法重載實現(xiàn)原理及代碼實例

    這篇文章主要介紹了Java方法重載實現(xiàn)原理及代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • 詳解Spring AOP

    詳解Spring AOP

    本文非常詳細講解了Spring AOP,本篇文章通過大量的代碼,講解了Spring AOP的使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java性能調優(yōu)及排查方式

    Java性能調優(yōu)及排查方式

    這篇文章主要介紹了Java性能調優(yōu)及排查方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Spring中的@Scope注解詳細講解及示例

    Spring中的@Scope注解詳細講解及示例

    這篇文章主要介紹了Spring中的@Scope注解詳細講解及示例,@Scope注解是 Spring IOC 容器中的一個作用域,在 Spring IOC 容器中,他用來配置Bean實例的作用域對象,需要的朋友可以參考下
    2023-11-11
  • Java中實現(xiàn)文件預覽的功能(實例代碼)

    Java中實現(xiàn)文件預覽的功能(實例代碼)

    大家都知道word,Excel,PPT實現(xiàn)在線預覽常用的方式就是先轉換成pdf,然后在進行預覽,下面給大家介紹Java中如何實現(xiàn)文件預覽的功能,需要的朋友可以參考下
    2023-05-05
  • Spring Boot 使用 Swagger 構建 RestAPI 接口文檔

    Spring Boot 使用 Swagger 構建 RestAPI 接口文檔

    這篇文章主要介紹了Spring Boot 使用 Swagger 構建 RestAPI 接口文檔,幫助大家更好的理解和使用Spring Boot框架,感興趣的朋友可以了解下
    2020-10-10
  • java使用Cookie判斷用戶登錄情況的方法

    java使用Cookie判斷用戶登錄情況的方法

    這篇文章主要為大家詳細介紹了java使用Cookie判斷用戶登錄情況,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java多線程編程之讀寫鎖ReadWriteLock用法實例

    Java多線程編程之讀寫鎖ReadWriteLock用法實例

    這篇文章主要介紹了Java多線程編程之讀寫鎖ReadWriteLock用法實例,本文直接給出編碼實例,需要的朋友可以參考下
    2015-05-05

最新評論