👉这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:
《项目实战(视频)》:从书中学,往事上“练”
《互联网高频面试题》:面朝简历学习,春暖花开
《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题
《精进 Java 学习指南》:系统学习,互联网主流技术栈
《必读 Java 源码专栏》:知其然,知其所以然
👉这是一个或许对你有用的开源项目
国产Star破10w的开源项目,前端包括管理后台、微信小程序,后端支持单体、微服务架构
RBAC权限、数据权限、SaaS多租户、商城、支付、工作流、大屏报表、ERP、CRM、AI大模型、IoT物联网等功能:
多模块:https://gitee.com/zhijiantianya/ruoyi-vue-pro
微服务:https://gitee.com/zhijiantianya/yudao-cloud
视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK17/21+SpringBoot3、JDK8/11+Spring Boot2双版本
来源:苏三说技术
系统架构设计
整体架构图
核心组件说明
异步导出流程详解
完整流程图
关键步骤分析
技术架构亮点
1. 策略模式 + 工厂模式
2. 注解驱动编程
3. 异步任务状态机
4. 分页大数据处理
技术优势
1. 用户体验优势
2. 系统性能优势
3. 开发维护优势
4. 运维管理优势
总结
核心技术栈
设计亮点
业务价值
在大型电商系统中,数据导出是一个高频且重要的功能需求。
传统的同步导出方式在面对大数据量时往往会导致请求超时、内存溢出等问题,严重影响用户体验。
苏三商城项目设计并实现了一套完整的Excel异步导出机制,通过注解驱动、任务队列、定时调度、消息通知等技术手段,完美解决了大数据量导出的技术难题,成为项目的技术亮点之一。
感兴趣的小伙伴,可以通过文末加入星球,学习完整的项目实战内容。
系统架构设计
整体架构图
核心组件说明
注解驱动层:通过
@ExcelExport注解实现声明式编程切面处理层:
CommonTaskAspect负责拦截和任务创建任务管理层:
ExcelExportTask执行具体的导出逻辑调度引擎层:基于Quartz的定时任务调度
消息通知层:RocketMQ + WebSocket实现异步通知
存储层:MySQL存储任务状态,OSS存储导出文件
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
异步导出流程详解
完整流程图
关键步骤分析
1. 注解驱动任务创建
@ExcelExport(ExcelBizTypeEnum.USER) @ApiOperation(notes = "导出用户数据", value = "导出用户数据") @PostMapping("/export") public void export(HttpServletResponse response, UserConditionEntity userConditionEntity) { // 方法体可以为空,切面会自动处理 }设计亮点:
声明式编程:通过注解实现功能声明,代码简洁
零侵入性:业务方法无需修改,切面自动处理
类型安全:通过枚举确保业务类型的正确性
2. 切面拦截与任务创建
@Aspect @Component publicclass CommonTaskAspect { @Before("@annotation(cn.net.susan.annotation.ExcelExport)") public void before(JoinPoint joinPoint) throws Throwable { // 获取注解信息 ExcelBizTypeEnum excelBizTypeEnum = method.getAnnotation(ExcelExport.class).value(); // 创建任务实体 CommonTaskEntity commonTaskEntity = createCommonTaskEntity(excelBizTypeEnum); // 保存任务到数据库 commonTaskMapper.insert(commonTaskEntity); } }技术特色:
AOP切面编程:实现横切关注点的分离
反射机制:动态获取注解信息和方法参数
任务持久化:将任务信息保存到数据库,确保可靠性
3. 定时任务调度机制
@Component publicclass CommonTaskJob extends BaseJob { @Override public JobResult doRun(String params) { // 查询待执行任务 CommonTaskConditionEntity condition = new CommonTaskConditionEntity(); condition.setStatusList(Arrays.asList( TaskStatusEnum.WAITING.getValue(), TaskStatusEnum.RUNNING.getValue() )); List<CommonTaskEntity> tasks = commonTaskMapper.searchByCondition(condition); // 执行任务 for (CommonTaskEntity task : tasks) { AsyncTaskStrategyContextFactory.getInstance() .getStrategy(task.getType()) .doTask(task); } return JobResult.SUCCESS; } }核心机制:
定时扫描:通过Quartz定时扫描任务队列
策略模式:根据任务类型选择对应的处理器
并发处理:支持多个任务并发执行
4. 异步任务处理器
@AsyncTask(TaskTypeEnum.EXPORT_EXCEL) @Service publicclass ExcelExportTask implements IAsyncTask { @Override public void doTask(CommonTaskEntity commonTaskEntity) { try { // 1. 更新任务状态为执行中 commonTaskEntity.setStatus(TaskStatusEnum.RUNNING.getValue()); commonTaskMapper.update(commonTaskEntity); // 2. 获取业务类型和请求参数 ExcelBizTypeEnum excelBizTypeEnum = getExcelBizTypeEnum(commonTaskEntity.getBizType()); String requestParam = commonTaskEntity.getRequestParam(); Object toBean = JSONUtil.toBean(requestParam, aClass); // 3. 获取对应的Service并执行导出 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. 更新任务状态为成功 commonTaskEntity.setFileUrl(fileUrl); commonTaskEntity.setStatus(TaskStatusEnum.SUCCESS.getValue()); } catch (Exception e) { // 5. 处理失败情况 handleTaskFailure(commonTaskEntity, e); } finally { // 6. 更新任务记录并发送通知 commonTaskMapper.update(commonTaskEntity); sendNotifyMessage(commonTaskEntity); } } }处理流程:
状态管理:完整的任务状态流转(等待→执行中→成功/失败)
异常处理:完善的异常捕获和失败重试机制
动态调用:通过反射动态获取Service实例
通知机制:任务完成后自动发送通知
5. 消息通知机制
@RocketMQMessageListener( topic = "${mall.mgt.excelExportTopic:EXCEL_EXPORT_TOPIC}", consumerGroup = "${mall.mgt.excelExportGroup:EXCEL_EXPORT_GROUP}") @Component publicclass 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); // 更新通知状态 commonNotifyEntity.setIsPush(1); commonNotifyMapper.update(commonNotifyEntity); } }通知特色:
异步解耦:通过消息队列实现系统解耦
实时推送:WebSocket确保用户及时收到通知
可靠性保证:消息队列确保通知的可靠传递
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud
视频教程:https://doc.iocoder.cn/video/
技术架构亮点
1. 策略模式 + 工厂模式
public class AsyncTaskStrategyContextFactory { private static Map<Integer, IAsyncTask> asyncTaskMap; public IAsyncTask getStrategy(Integer taskType) { return asyncTaskMap.get(taskType); } }设计优势:
扩展性强:新增任务类型只需实现
IAsyncTask接口维护性好:每种任务类型独立实现,互不影响
配置灵活:通过工厂模式统一管理任务策略
2. 注解驱动编程
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ExcelExport { ExcelBizTypeEnum value(); }编程范式:
声明式编程:通过注解声明功能,而非命令式实现
元数据驱动:注解携带的元数据驱动系统行为
代码简洁:业务代码保持简洁,关注点分离
3. 异步任务状态机
状态管理:
状态流转:清晰的状态转换逻辑
重试机制:失败任务自动重试,提高成功率
状态持久化:任务状态持久化到数据库
4. 分页大数据处理
private String doExport(V v, String fileName, String clazzName) { RequestConditionEntity conditionEntity = (RequestConditionEntity) v; // 计算分页参数 int totalCount = getBaseMapper().searchCount(conditionEntity); int sheetCount = totalCount % sheetDataSize == 0 ? totalCount / sheetDataSize : totalCount / sheetDataSize + 1; // 创建ExcelWriter ExcelWriter excelWriter = EasyExcel.write(file).build(); // 分页处理数据 for (int sheetIndex = 1; sheetIndex <= sheetCount; sheetIndex++) { List<K> dataEntities = getBaseMapper().searchByCondition(conditionEntity); // 写入数据到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); }处理策略:
内存优化:分页查询避免大量数据加载到内存
流式处理:使用EasyExcel的流式API
多Sheet支持:大数据自动分割到多个Sheet
进度可控:分页处理便于监控和中断
技术优势
1. 用户体验优势
即时响应:用户请求后立即返回,无需等待
实时通知:通过WebSocket实时推送导出结果
进度可见:用户可以实时查看导出进度
错误友好:导出失败时提供详细的错误信息
2. 系统性能优势
高并发:异步处理支持高并发导出请求
资源优化:分页处理避免内存溢出
负载均衡:任务队列支持负载均衡
可扩展性:支持水平扩展和垂直扩展
3. 开发维护优势
代码简洁:注解驱动,业务代码简洁
易于扩展:新增业务类型只需添加注解
统一管理:所有导出任务统一管理和监控
错误处理:完善的异常处理和重试机制
4. 运维管理优势
任务监控:完整的任务执行监控
状态管理:清晰的任务状态流转
日志记录:详细的操作日志记录
告警机制:完善的异常告警机制
总结
苏三商城的Excel异步导出机制是一个设计精良、功能完善的企业级解决方案。
它通过以下技术手段实现了高效、稳定、可扩展的异步导出功能:
核心技术栈
注解驱动:
@ExcelExport注解实现声明式编程AOP切面:
CommonTaskAspect实现横切关注点分离策略模式:
AsyncTaskStrategyContextFactory实现任务策略管理定时调度:Quartz实现任务定时调度
消息队列:RocketMQ实现异步通知
实时通信:WebSocket实现实时推送
文件存储:OSS实现文件云端存储
设计亮点
异步解耦:通过任务队列实现请求与处理的解耦
状态管理:完整的任务状态流转和持久化
错误处理:完善的异常处理和重试机制
性能优化:分页处理、流式写入、内存优化
扩展性强:支持业务类型、导出格式、通知方式的扩展
业务价值
提升用户体验:异步处理避免长时间等待
提高系统性能:支持大数据量导出和高并发请求
降低开发成本:注解驱动减少重复代码
便于运维管理:统一的任务管理和监控
这套异步导出机制不仅解决了传统同步导出的技术难题,还提供了良好的扩展性和维护性,是苏三商城项目的技术亮点之一,值得在其他项目中推广和应用。
欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,“长按”或“扫描”下方二维码噢:
星球的内容包括:项目实战、面试招聘、源码解析、学习路线。
文章有帮助的话,在看,转发吧。 谢谢支持哟 (*^__^*)