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

java實(shí)現(xiàn)Excel高性能異步導(dǎo)出的完整方案詳解

 更新時(shí)間:2025年10月28日 08:14:11   作者:蘇三說技術(shù)  
在大型電商系統(tǒng)中,數(shù)據(jù)導(dǎo)出是一個(gè)高頻且重要的功能需求,本文將設(shè)計(jì)實(shí)現(xiàn)一套完整的Excel異步導(dǎo)出機(jī)制,通過注解驅(qū)動(dòng)、任務(wù)隊(duì)列、定時(shí)調(diào)度、消息通知等技術(shù)手段,完美解決了大數(shù)據(jù)量導(dǎo)出的技術(shù)難題,成為項(xiàng)目的重要技術(shù)亮點(diǎn)

前言

在大型電商系統(tǒng)中,數(shù)據(jù)導(dǎo)出是一個(gè)高頻且重要的功能需求。

傳統(tǒng)的同步導(dǎo)出方式在面對(duì)大數(shù)據(jù)量時(shí)往往會(huì)導(dǎo)致請(qǐng)求超時(shí)、內(nèi)存溢出等問題,嚴(yán)重影響用戶體驗(yàn)。

蘇三商城項(xiàng)目創(chuàng)新性地設(shè)計(jì)并實(shí)現(xiàn)了一套完整的Excel異步導(dǎo)出機(jī)制,通過注解驅(qū)動(dòng)、任務(wù)隊(duì)列、定時(shí)調(diào)度、消息通知等技術(shù)手段,完美解決了大數(shù)據(jù)量導(dǎo)出的技術(shù)難題,成為項(xiàng)目的重要技術(shù)亮點(diǎn)。

系統(tǒng)架構(gòu)設(shè)計(jì)

整體架構(gòu)圖

核心組件說明

  • 注解驅(qū)動(dòng)層:通過@ExcelExport注解實(shí)現(xiàn)聲明式編程
  • 切面處理層CommonTaskAspect負(fù)責(zé)攔截和任務(wù)創(chuàng)建
  • 任務(wù)管理層ExcelExportTask執(zhí)行具體的導(dǎo)出邏輯
  • 調(diào)度引擎層:基于Quartz的定時(shí)任務(wù)調(diào)度
  • 消息通知層:RocketMQ + WebSocket實(shí)現(xiàn)異步通知
  • 存儲(chǔ)層:MySQL存儲(chǔ)任務(wù)狀態(tài),OSS存儲(chǔ)導(dǎo)出文件

異步導(dǎo)出流程詳解

完整流程圖

關(guān)鍵步驟分析

1. 注解驅(qū)動(dòng)任務(wù)創(chuàng)建

@ExcelExport(ExcelBizTypeEnum.USER)
@ApiOperation(notes = "導(dǎo)出用戶數(shù)據(jù)", value = "導(dǎo)出用戶數(shù)據(jù)")
@PostMapping("/export")
public void export(HttpServletResponse response, UserConditionEntity userConditionEntity) {
    // 方法體可以為空,切面會(huì)自動(dòng)處理
}

設(shè)計(jì)亮點(diǎn)

  • 聲明式編程:通過注解實(shí)現(xiàn)功能聲明,代碼簡潔
  • 零侵入性:業(yè)務(wù)方法無需修改,切面自動(dòng)處理
  • 類型安全:通過枚舉確保業(yè)務(wù)類型的正確性

2. 切面攔截與任務(wù)創(chuàng)建

@Aspect
@Component
public class CommonTaskAspect {
    
    @Before("@annotation(cn.net.susan.annotation.ExcelExport)")
    public void before(JoinPoint joinPoint) throws Throwable {
        // 獲取注解信息
        ExcelBizTypeEnum excelBizTypeEnum = method.getAnnotation(ExcelExport.class).value();
        
        // 創(chuàng)建任務(wù)實(shí)體
        CommonTaskEntity commonTaskEntity = createCommonTaskEntity(excelBizTypeEnum);
        
        // 保存任務(wù)到數(shù)據(jù)庫
        commonTaskMapper.insert(commonTaskEntity);
    }
}

技術(shù)特色

  • AOP切面編程:實(shí)現(xiàn)橫切關(guān)注點(diǎn)的分離
  • 反射機(jī)制:動(dòng)態(tài)獲取注解信息和方法參數(shù)
  • 任務(wù)持久化:將任務(wù)信息保存到數(shù)據(jù)庫,確保可靠性

3. 定時(shí)任務(wù)調(diào)度機(jī)制

@Component
public class CommonTaskJob extends BaseJob {
    
    @Override
    public JobResult doRun(String params) {
        // 查詢待執(zhí)行任務(wù)
        CommonTaskConditionEntity condition = new CommonTaskConditionEntity();
        condition.setStatusList(Arrays.asList(
            TaskStatusEnum.WAITING.getValue(),
            TaskStatusEnum.RUNNING.getValue()
        ));
        
        List<CommonTaskEntity> tasks = commonTaskMapper.searchByCondition(condition);
        
        // 執(zhí)行任務(wù)
        for (CommonTaskEntity task : tasks) {
            AsyncTaskStrategyContextFactory.getInstance()
                .getStrategy(task.getType())
                .doTask(task);
        }
        
        return JobResult.SUCCESS;
    }
}

核心機(jī)制

  • 定時(shí)掃描:通過Quartz定時(shí)掃描任務(wù)隊(duì)列
  • 策略模式:根據(jù)任務(wù)類型選擇對(duì)應(yīng)的處理器
  • 并發(fā)處理:支持多個(gè)任務(wù)并發(fā)執(zhí)行

4. 異步任務(wù)處理器

@AsyncTask(TaskTypeEnum.EXPORT_EXCEL)
@Service
public class ExcelExportTask implements IAsyncTask {
    
    @Override
    public void doTask(CommonTaskEntity commonTaskEntity) {
        try {
            // 1. 更新任務(wù)狀態(tài)為執(zhí)行中
            commonTaskEntity.setStatus(TaskStatusEnum.RUNNING.getValue());
            commonTaskMapper.update(commonTaskEntity);
            
            // 2. 獲取業(yè)務(wù)類型和請(qǐng)求參數(shù)
            ExcelBizTypeEnum excelBizTypeEnum = getExcelBizTypeEnum(commonTaskEntity.getBizType());
            String requestParam = commonTaskEntity.getRequestParam();
            Object toBean = JSONUtil.toBean(requestParam, aClass);
            
            // 3. 獲取對(duì)應(yīng)的Service并執(zhí)行導(dǎo)出
            String serviceName = this.getServiceName(requestEntity);
            BaseService baseService = (BaseService) SpringBeanUtil.getBean(serviceName);
            String fileName = getFileName(excelBizTypeEnum.getDesc());
            String fileUrl = baseService.export(toBean, fileName, this.getEntityName(requestEntity));
            
            // 4. 更新任務(wù)狀態(tài)為成功
            commonTaskEntity.setFileUrl(fileUrl);
            commonTaskEntity.setStatus(TaskStatusEnum.SUCCESS.getValue());
            
        } catch (Exception e) {
            // 5. 處理失敗情況
            handleTaskFailure(commonTaskEntity, e);
        } finally {
            // 6. 更新任務(wù)記錄并發(fā)送通知
            commonTaskMapper.update(commonTaskEntity);
            sendNotifyMessage(commonTaskEntity);
        }
    }
}

處理流程

  • 狀態(tài)管理:完整的任務(wù)狀態(tài)流轉(zhuǎn)(等待→執(zhí)行中→成功/失?。?/li>
  • 異常處理:完善的異常捕獲和失敗重試機(jī)制
  • 動(dòng)態(tài)調(diào)用:通過反射動(dòng)態(tài)獲取Service實(shí)例
  • 通知機(jī)制:任務(wù)完成后自動(dòng)發(fā)送通知

5. 消息通知機(jī)制

@RocketMQMessageListener(
    topic = "${mall.mgt.excelExportTopic:EXCEL_EXPORT_TOPIC}",
    consumerGroup = "${mall.mgt.excelExportGroup:EXCEL_EXPORT_GROUP}"
)
@Component
public class ExcelExportConsumer implements RocketMQListener<MessageExt> {
    
    @Override
    public void onMessage(MessageExt message) {
        String content = new String(message.getBody());
        CommonNotifyEntity commonNotifyEntity = JSONUtil.toBean(content, CommonNotifyEntity.class);
        pushNotify(commonNotifyEntity);
    }
    
    private void pushNotify(CommonNotifyEntity commonNotifyEntity) {
        // 通過WebSocket推送通知
        WebSocketServer.sendMessage(commonNotifyEntity);
        
        // 更新通知狀態(tài)
        commonNotifyEntity.setIsPush(1);
        commonNotifyMapper.update(commonNotifyEntity);
    }
}

通知特色

  • 異步解耦:通過消息隊(duì)列實(shí)現(xiàn)系統(tǒng)解耦
  • 實(shí)時(shí)推送:WebSocket確保用戶及時(shí)收到通知
  • 可靠性保證:消息隊(duì)列確保通知的可靠傳遞

技術(shù)架構(gòu)亮點(diǎn)

1. 策略模式 + 工廠模式

public class AsyncTaskStrategyContextFactory {
    private static Map<Integer, IAsyncTask> asyncTaskMap;
    
    public IAsyncTask getStrategy(Integer taskType) {
        return asyncTaskMap.get(taskType);
    }
}

設(shè)計(jì)優(yōu)勢(shì)

  • 擴(kuò)展性強(qiáng):新增任務(wù)類型只需實(shí)現(xiàn)IAsyncTask接口
  • 維護(hù)性好:每種任務(wù)類型獨(dú)立實(shí)現(xiàn),互不影響
  • 配置靈活:通過工廠模式統(tǒng)一管理任務(wù)策略

2. 注解驅(qū)動(dòng)編程

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelExport {
    ExcelBizTypeEnum value();
}

編程范式

  • 聲明式編程:通過注解聲明功能,而非命令式實(shí)現(xiàn)
  • 元數(shù)據(jù)驅(qū)動(dòng):注解攜帶的元數(shù)據(jù)驅(qū)動(dòng)系統(tǒng)行為
  • 代碼簡潔:業(yè)務(wù)代碼保持簡潔,關(guān)注點(diǎn)分離

3. 異步任務(wù)狀態(tài)機(jī)

狀態(tài)管理

  • 狀態(tài)流轉(zhuǎn):清晰的狀態(tài)轉(zhuǎn)換邏輯
  • 重試機(jī)制:失敗任務(wù)自動(dòng)重試,提高成功率
  • 狀態(tài)持久化:任務(wù)狀態(tài)持久化到數(shù)據(jù)庫

4. 分頁大數(shù)據(jù)處理

private String doExport(V v, String fileName, String clazzName) {
    RequestConditionEntity conditionEntity = (RequestConditionEntity) v;
    
    // 計(jì)算分頁參數(shù)
    int totalCount = getBaseMapper().searchCount(conditionEntity);
    int sheetCount = totalCount % sheetDataSize == 0 ? 
        totalCount / sheetDataSize : totalCount / sheetDataSize + 1;
    
    // 創(chuàng)建ExcelWriter
    ExcelWriter excelWriter = EasyExcel.write(file).build();
    
    // 分頁處理數(shù)據(jù)
    for (int sheetIndex = 1; sheetIndex <= sheetCount; sheetIndex++) {
        List<K> dataEntities = getBaseMapper().searchByCondition(conditionEntity);
        
        // 寫入數(shù)據(jù)到Sheet
        WriteSheet writeSheet = EasyExcel.writerSheet("Sheet" + sheetIndex)
            .head(Class.forName(clazzName)).build();
        excelWriter.write(dataEntities, writeSheet);
        
        conditionEntity.setPageNo(conditionEntity.getPageNo() + 1);
    }
    
    excelWriter.finish();
    return uploadToOSS(file);
}

處理策略

  • 內(nèi)存優(yōu)化:分頁查詢避免大量數(shù)據(jù)加載到內(nèi)存
  • 流式處理:使用EasyExcel的流式API
  • 多Sheet支持:大數(shù)據(jù)自動(dòng)分割到多個(gè)Sheet
  • 進(jìn)度可控:分頁處理便于監(jiān)控和中斷

技術(shù)優(yōu)勢(shì)

1. 用戶體驗(yàn)優(yōu)勢(shì)

  • 即時(shí)響應(yīng):用戶請(qǐng)求后立即返回,無需等待
  • 實(shí)時(shí)通知:通過WebSocket實(shí)時(shí)推送導(dǎo)出結(jié)果
  • 進(jìn)度可見:用戶可以實(shí)時(shí)查看導(dǎo)出進(jìn)度
  • 錯(cuò)誤友好:導(dǎo)出失敗時(shí)提供詳細(xì)的錯(cuò)誤信息

2. 系統(tǒng)性能優(yōu)勢(shì)

  • 高并發(fā):異步處理支持高并發(fā)導(dǎo)出請(qǐng)求
  • 資源優(yōu)化:分頁處理避免內(nèi)存溢出
  • 負(fù)載均衡:任務(wù)隊(duì)列支持負(fù)載均衡
  • 可擴(kuò)展性:支持水平擴(kuò)展和垂直擴(kuò)展

3. 開發(fā)維護(hù)優(yōu)勢(shì)

  • 代碼簡潔:注解驅(qū)動(dòng),業(yè)務(wù)代碼簡潔
  • 易于擴(kuò)展:新增業(yè)務(wù)類型只需添加注解
  • 統(tǒng)一管理:所有導(dǎo)出任務(wù)統(tǒng)一管理和監(jiān)控
  • 錯(cuò)誤處理:完善的異常處理和重試機(jī)制

4. 運(yùn)維管理優(yōu)勢(shì)

  • 任務(wù)監(jiān)控:完整的任務(wù)執(zhí)行監(jiān)控
  • 狀態(tài)管理:清晰的任務(wù)狀態(tài)流轉(zhuǎn)
  • 日志記錄:詳細(xì)的操作日志記錄
  • 告警機(jī)制:完善的異常告警機(jī)制

總結(jié)

蘇三商城的Excel異步導(dǎo)出機(jī)制是一個(gè)設(shè)計(jì)精良、功能完善的企業(yè)級(jí)解決方案。

它通過以下技術(shù)手段實(shí)現(xiàn)了高效、穩(wěn)定、可擴(kuò)展的異步導(dǎo)出功能:

核心技術(shù)棧

  • 注解驅(qū)動(dòng)@ExcelExport注解實(shí)現(xiàn)聲明式編程
  • AOP切面CommonTaskAspect實(shí)現(xiàn)橫切關(guān)注點(diǎn)分離
  • 策略模式AsyncTaskStrategyContextFactory實(shí)現(xiàn)任務(wù)策略管理
  • 定時(shí)調(diào)度:Quartz實(shí)現(xiàn)任務(wù)定時(shí)調(diào)度
  • 消息隊(duì)列:RocketMQ實(shí)現(xiàn)異步通知
  • 實(shí)時(shí)通信:WebSocket實(shí)現(xiàn)實(shí)時(shí)推送
  • 文件存儲(chǔ):OSS實(shí)現(xiàn)文件云端存儲(chǔ)

設(shè)計(jì)亮點(diǎn)

  • 異步解耦:通過任務(wù)隊(duì)列實(shí)現(xiàn)請(qǐng)求與處理的解耦
  • 狀態(tài)管理:完整的任務(wù)狀態(tài)流轉(zhuǎn)和持久化
  • 錯(cuò)誤處理:完善的異常處理和重試機(jī)制
  • 性能優(yōu)化:分頁處理、流式寫入、內(nèi)存優(yōu)化
  • 擴(kuò)展性強(qiáng):支持業(yè)務(wù)類型、導(dǎo)出格式、通知方式的擴(kuò)展
  • 監(jiān)控完善:完整的任務(wù)監(jiān)控和告警機(jī)制

業(yè)務(wù)價(jià)值

  • 提升用戶體驗(yàn):異步處理避免長時(shí)間等待
  • 提高系統(tǒng)性能:支持大數(shù)據(jù)量導(dǎo)出和高并發(fā)請(qǐng)求
  • 降低開發(fā)成本:注解驅(qū)動(dòng)減少重復(fù)代碼
  • 便于運(yùn)維管理:統(tǒng)一的任務(wù)管理和監(jiān)控

這套異步導(dǎo)出機(jī)制不僅解決了傳統(tǒng)同步導(dǎo)出的技術(shù)難題,還提供了良好的擴(kuò)展性和維護(hù)性,是蘇三商城項(xiàng)目的技術(shù)亮點(diǎn)之一,值得在其他項(xiàng)目中推廣和應(yīng)用。

到此這篇關(guān)于java實(shí)現(xiàn)Excel高性能異步導(dǎo)出的完整方案詳解的文章就介紹到這了,更多相關(guān)java Excel異步導(dǎo)出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis與Spring中的SqlSession詳解

    MyBatis與Spring中的SqlSession詳解

    在MyBatis中,你可以使用SqlSessionFactory來創(chuàng)建SqlSession,使用MyBatis-Spring之后,你不再需要直接使用SqlSessionFactory了,接下來通過示例代碼講解MyBatis與Spring中的SqlSession,需要的朋友可以參考下
    2024-05-05
  • java中將一個(gè)List等分成n個(gè)list的工具方法(推薦)

    java中將一個(gè)List等分成n個(gè)list的工具方法(推薦)

    下面小編就為大家?guī)硪黄猨ava中將一個(gè)List等分成n個(gè)list的工具方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java正則提取中括號(hào)中的內(nèi)容操作示例

    Java正則提取中括號(hào)中的內(nèi)容操作示例

    這篇文章主要介紹了Java正則提取中括號(hào)中的內(nèi)容操作,涉及Java針對(duì)字符串的正則匹配、轉(zhuǎn)換、遍歷等相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • Java學(xué)習(xí)筆記之異常處理

    Java學(xué)習(xí)筆記之異常處理

    這篇文章主要為大家詳細(xì)介紹了Java學(xué)習(xí)筆記之異常處理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Spring Boot異常處理try-catch應(yīng)該怎么使用?

    Spring Boot異常處理try-catch應(yīng)該怎么使用?

    這篇文章詳細(xì)介紹了Web系統(tǒng)中異常處理的重要性,以及SpringMVC的異常處理機(jī)制,解釋了異常在系統(tǒng)中的角色,討論了Java異常模型的關(guān)鍵認(rèn)知,包括Throwable體系結(jié)構(gòu)和異常傳播,強(qiáng)調(diào)了在Web系統(tǒng)中不應(yīng)該到處使用try-catch,而是應(yīng)該在邊界層統(tǒng)一處理異常
    2026-01-01
  • 解決Spring AOP 同類調(diào)用失效問題

    解決Spring AOP 同類調(diào)用失效問題

    這篇文章主要介紹了解決Spring AOP 同類調(diào)用失效問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java經(jīng)典算法之快速排序詳解

    Java經(jīng)典算法之快速排序詳解

    這篇文章主要給大家介紹了關(guān)于Java經(jīng)典算法之快速排序的相關(guān)資料,需快速排序是一種分治法的排序算法,其基本思想是通過一趟排序?qū)⒋判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有元素均比另一部分的元素小,然后分別對(duì)這兩部分繼續(xù)進(jìn)行排序,需要的朋友可以參考下
    2024-07-07
  • 關(guān)于報(bào)錯(cuò)IDEA Terminated with exit code 1的解決方法

    關(guān)于報(bào)錯(cuò)IDEA Terminated with exit code 

    如果在IDEA構(gòu)建項(xiàng)目時(shí)遇到下面這樣的報(bào)錯(cuò)IDEA Terminated with exit code 1,那必然是Maven的設(shè)置參數(shù)重置了,導(dǎo)致下載錯(cuò)誤引起的,本文給大家分享兩種解決方法,需要的朋友可以參考下
    2022-08-08
  • java中多線程加鎖的四種方式

    java中多線程加鎖的四種方式

    Java中實(shí)現(xiàn)多線程安全的關(guān)鍵是加鎖,主要方式有synchronized關(guān)鍵字、ReentrantLock類、ReadWriteLock接口和Semaphore類,本文就來介紹一下這四種方式,感興趣的可以了解一下
    2024-10-10
  • Spring Boot Starter 封裝的實(shí)現(xiàn)示例

    Spring Boot Starter 封裝的實(shí)現(xiàn)示例

    Spring Boot Starter封裝了項(xiàng)目中常用的一些依賴,使得開發(fā)者可以快速啟動(dòng)和運(yùn)行項(xiàng)目,而無需手動(dòng)配置這些依賴,下面就來詳細(xì)的介紹一下如何實(shí)現(xiàn),感興趣的可以了解一下
    2025-09-09

最新評(píng)論

东乌珠穆沁旗| 陆丰市| 鄯善县| 迭部县| 文登市| 诸城市| 酒泉市| 三门峡市| 清丰县| 株洲县| 临泽县| 九龙县| 沂源县| 鄂托克前旗| 尉犁县| 辉县市| 开封县| 黄山市| 庆城县| 上饶县| 津市市| 东光县| 吴忠市| 安新县| 新津县| 白山市| 中西区| 抚顺市| 平果县| 新津县| 曲水县| 祁门县| 武冈市| 县级市| 东城区| 萍乡市| 遵义市| 济源市| 衡南县| 博兴县| 博乐市|