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

Java解析嵌套jar中class文件過程

 更新時(shí)間:2026年04月22日 08:33:51   作者:繡花針  
本文介紹了兩種解析嵌套jar中的class文件的方式,一種是使用`spring-boot-loader`中的`JarFileArchive`,另一種是使用`JarFile`,通過實(shí)測對(duì)比了兩種方式的性能差異,結(jié)果表明`JarFile`方式略慢于`JarFileArchive`方式

一、簡述

Maven項(xiàng)目通過package打成jar包后,jar包中包含所有依賴lib文件。

本文介紹了兩種方式解析嵌套jar中的class文件,一種是通過spring-boot-loader包JarFileArchive,另一種是util包中JarFile。

二、JarFileArchive方式

1.spring-boot-loader依賴引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-loader</artifactId>
    <version>2.2.4.RELEASE</version>
</dependency>

2.demo案例

不同版本的spring-boot-loader,getNestedArchives(EntryFilter filter)有所變化(高版本中已廢棄,使用getNestedArchives(EntryFilter searchFilter,EntryFilter includeFilter))。

可以跟進(jìn)對(duì)應(yīng)版本spring-boot-loader源碼進(jìn)行調(diào)整。

   public static void main(String args[]) throws Exception {
        String jarPath = "C:\\Users\\root\\Desktop\\make-test.jar";
		// 方案一:spring-boot-loader
        long start1 = System.currentTimeMillis();
        getClassInfoByJarLib(jarPath);
        long end1 = System.currentTimeMillis();
        log.info("收集所有l(wèi)ib類ClassInfo,花費(fèi)時(shí)間={}",(end1-start1));
    } 

    public static void getClassInfoByJarLib(String jarPath) {
        String filePath;
        String separator = File.separator;
        if("\\".equals(separator)){
            // windows系統(tǒng)使用如下路徑
            filePath = "file:/"+ URLDecoder.decode(jarPath, StandardCharsets.UTF_8).replaceAll("\\\\","/")+"!/";
        }else if("/".equals(separator)){
            // linux系統(tǒng)使用如下路徑
            filePath = "file:"+ URLDecoder.decode(jarPath, StandardCharsets.UTF_8).replaceAll("\\\\","/")+"!/";
        }else {
             throw new RuntimeException("未知操作系統(tǒng),解析jarLib失敗");
        } 
        String rootJarPath = "jar:"+ filePath;
        try {
            JarFileArchive jarFileArchive = new JarFileArchive(new Handler().getRootJarFileFromUrl(new URL(rootJarPath)));
            //getNestedArchives獲取嵌套的jar等文件,參數(shù)是個(gè)EntryFilter,過濾條件
            jarFileArchive.getNestedArchives(entry -> entry.getName().startsWith("BOOT-INF/lib/") && entry.getName().endsWith(".jar"))
                    .forEach(archive -> {
                        archive.iterator().forEachRemaining(entry -> {
                            String entryName = entry.getName();
                            // 過濾嵌套jar包中字節(jié)碼文件
                            if (entryName.endsWith(".class")) {
                                String className = entryName.replace('/', '.').replace(".class", "");
                                log.info("className:{}",className);
                            }
                        });
                    });
        } catch (IOException e) {
            log.error("解析嵌套jarLib中ClassInfo異常,jarPath={}",jarPath,e);
            throw new RuntimeException(e);
        }
    }

三、JarFile方式

1.demo案例

   public static void main(String args[]) throws Exception {
        String jarPath = "C:\\Users\\root\\Desktop\\make-test.jar";
		// 方案二:JarFile
        long start2 = System.currentTimeMillis();
        processJar(jarPath);
        long end2 = System.currentTimeMillis();
        log.info("收集所有l(wèi)ib類ClassInfo,花費(fèi)時(shí)間={}",(end2-start2));
    } 
    private static void processJar(String jarPath){
        try (JarFile jarFile = new JarFile(new File(jarPath))) {
            jarFile.stream().parallel()
                    // 過濾出所有符合要求的jar包
                    .filter(entry -> !entry.isDirectory() && entry.getName().startsWith("BOOT-INF/lib/") && entry.getName().endsWith(".jar"))
                    .forEach(entry -> processNestedJar(jarFile, entry.getName()));
        } catch (IOException e) {
            log.error("解析嵌套jarLib中ClassInfo異常,jarPath={}",jarPath,e);
            throw new RuntimeException(e);
        }
    }

    private static void processNestedJar(JarFile jarFile, String entryName){
        // 處理嵌套jar文件
        try (InputStream nestedJarStream = jarFile.getInputStream(jarFile.getJarEntry(entryName));
            JarInputStream jarInputStream = new JarInputStream(nestedJarStream)) {
            JarEntry nestedEntry;
            while ((nestedEntry = jarInputStream.getNextJarEntry()) != null) {
                if (nestedEntry.isDirectory()) {
                    continue;
                }
                String nestedEntryName = nestedEntry.getName();
                if (!nestedEntryName.endsWith(".class")) {
                    continue;
                }
                try {
                    String className = nestedEntryName.replace('/', '.').replace(".class", "");
					log.info("className:{}",className);
                } catch (Exception e) {
                    log.error("目標(biāo)類={}查找失敗",nestedEntryName,e);
					throw new RuntimeException(e);
                }
            }
        } catch (IOException e) {
		    log.error("目標(biāo)類={}查找失敗",entryName,e);
            throw new RuntimeException(e);
        }
    }

四、兩種方式對(duì)比

實(shí)測項(xiàng)目make-test.jar中所有依賴lib約200個(gè),其中所有class字節(jié)碼文件約7萬多個(gè)。

方案JarFileArchive約1.5s全部解析,方案JarFile約6s全部解析。

總結(jié)

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

相關(guān)文章

  • Java之@TableField注解的用法解析

    Java之@TableField注解的用法解析

    MyBatis-Plus的@TableField注解用于控制實(shí)體類字段與數(shù)據(jù)庫表字段的映射關(guān)系,支持字段映射、忽略、插入和更新控制、自定義填充策略和類型轉(zhuǎn)換等
    2025-01-01
  • Java正則驗(yàn)證電話,手機(jī),郵箱,日期,金額的方法示例

    Java正則驗(yàn)證電話,手機(jī),郵箱,日期,金額的方法示例

    這篇文章主要介紹了Java正則驗(yàn)證電話,手機(jī),郵箱,日期,金額的方法,結(jié)合具體實(shí)例形式分析了Java針對(duì)電話,手機(jī),郵箱,日期,金額的正則判定操作技巧,需要的朋友可以參考下
    2017-03-03
  • Java servlet、filter、listener、interceptor之間的區(qū)別和聯(lián)系

    Java servlet、filter、listener、interceptor之間的區(qū)別和聯(lián)系

    這篇文章主要介紹了Java servlet、filter、listener、interceptor之間的區(qū)別和聯(lián)系的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • 詳解Java線程中斷知識(shí)點(diǎn)

    詳解Java線程中斷知識(shí)點(diǎn)

    在本篇文章中我們給大家分享了關(guān)于Java線程中斷的相關(guān)知識(shí)點(diǎn)內(nèi)容以及相關(guān)代碼實(shí)例,有興趣的朋友們可以學(xué)習(xí)下。
    2018-09-09
  • Mac M1 Maven安裝與配置教程

    Mac M1 Maven安裝與配置教程

    文章詳細(xì)介紹了Maven的安裝配置步驟,包括下載解壓、設(shè)置環(huán)境變量路徑、編輯bash_profile文件,以及修改settings.xml配置本地倉庫和鏡像源,最后通過mvn -v驗(yàn)證配置是否成功
    2025-09-09
  • Spring中@Validated和@Valid區(qū)別淺析

    Spring中@Validated和@Valid區(qū)別淺析

    @Valid是javax.validation里的,?@Validated是@Valid?的一次封裝,是Spring提供的校驗(yàn)機(jī)制使用,下面這篇文章主要給大家介紹了關(guān)于Spring中@Validated和@Valid區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • SpringBoot2線程池定義使用方法解析

    SpringBoot2線程池定義使用方法解析

    這篇文章主要介紹了SpringBoot2線程池定義使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java線程組操作實(shí)例分析

    Java線程組操作實(shí)例分析

    這篇文章主要介紹了Java線程組操作,結(jié)合實(shí)例形式分析了ThreadGroup類創(chuàng)建與使用線程組相關(guān)操作技巧,需要的朋友可以參考下
    2019-09-09
  • 深入剖析Java中Map.Entry的方法與實(shí)戰(zhàn)應(yīng)用

    深入剖析Java中Map.Entry的方法與實(shí)戰(zhàn)應(yīng)用

    在Java集合框架中,Map.Entry扮演著連接鍵值對(duì)的橋梁角色,作為Map接口的內(nèi)部接口,它封裝了鍵值對(duì)的本質(zhì),是高效處理映射數(shù)據(jù)的核心工具,下面我我們就來深入剖析Map.Entry的概念,方法及實(shí)戰(zhàn)應(yīng)用
    2025-06-06
  • JavaWeb文件上傳入門教程

    JavaWeb文件上傳入門教程

    這篇文章主要為大家詳細(xì)介紹了JavaWeb文件上傳入門教程,分析了文件上傳原理、介紹了第三方上傳組件,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評(píng)論

岳阳市| 全椒县| 廉江市| 松江区| 张掖市| 军事| 四会市| 铜梁县| 信阳市| 沅陵县| 印江| 靖边县| 府谷县| 屏东县| 淳化县| 连江县| 滨州市| 安福县| 房产| 福泉市| 驻马店市| 丽江市| 濮阳县| 德令哈市| 阿鲁科尔沁旗| 德庆县| 五河县| 罗定市| 翁牛特旗| 犍为县| 尖扎县| 安平县| 澄迈县| 昌黎县| 莱芜市| 汝城县| 化隆| 长白| 鲜城| 巴彦淖尔市| 九龙城区|