CompletableFuture 介绍
CompletableFuture 是 Java 8 引入的一个强大工具,用于处理异步编程。它实现了 Future 和 CompletionStage 接口,提供了丰富的方法来组合、编排和管理异步任务。
由于个人工作的原因经常用到异步导出,所以搞了一个异步导出工具类分享出来
@Slf4j
@Component
public class AsyncUtil {
//"[" + XXXX + "][" + YYYY + "]" + sheetName
public static String TEMPLATE_LOCK_1="[{}][{}] {}";
private static SendAsyncTaskUtil sendAsyncTaskUtil;
private static RedissonClient redissonClient;
@PostConstruct // 推荐方式
public void init() throws Exception {
// 初始化逻辑
redissonClient = SpringContextHolder.getBean(RedissonClient.class);
sendAsyncTaskUtil = SpringContextHolder.getBean(SendAsyncTaskUtil.class);
}
public static ResultVO asyncExport(String fileName,String lockKey,
AsyncExportEnum asyncExportEnum, ExecuteFunction function, Executor executor) {
Assert.notNull(executor);
log.info("asyncExport : start ======================== lockKey:{}", StringUtil.escapeJava(lockKey));
UserEntity userEntity = UserHelper.getSessionUser();
log.info("asyncExport : ======================== userId:{}", StringUtil.escapeJava(userEntity.getUserID()));
RLock lock = redissonClient.getLock(lockKey + userEntity.getUserID());
if (lock.isLocked()) {
return ResultVOHelper.operError("1", lockKey);
}
String taskId = StringHelper.GetGUID();
String realToken = StringHelper.GetGUID();
String message = I18nHelper.getPropertiesSource("2", null, lockKey);
Locale locale = LocaleContextHolder.getLocale();
//时区处理
String timeZone = (String) RequestParamsContextUtils.get(TIME_ZONE_HEADER);
CompletableFuture.supplyAsync(() -> {
lock.lock();
LocaleContextHolder.setLocale(locale);
TokenThreadLocal.setToken(realToken);
SessionHelper.put(realToken, userEntity);
//时区处理 FastThreadLocal<Map<String, Object>> threadLocal
RequestParamsContextUtils.set(TIME_ZONE_HEADER, timeZone);
sendAsyncTaskUtil.sendBackAsyncTask(taskId, asyncExportEnum.getVal(), message, message, null
, userEntity, ON_GOING);
//将文件上传S3
try (Workbook wb = function.execute()) {
//return exportAsync(searchvo, response);
//导出工具类
return ExcelUtils.excelExport(wb, fileName, 2, null);
}catch (Exception e) {
log.warn("asyncExport : Exception-1 ========================", e);
throw new Exception("2", null, lockKey);
}
}, executor).whenComplete((result, exception) -> {
lock.unlock();
log.info("asyncExport : Method Result ======================== result:{}", StringUtil.escapeJava(result.getMsg()));
if (exception != null) {
log.error("asyncExport : Exception-2 ======================== error:{}", exception);
String msg = I18nHelper.getPropertiesSource("3", null, lockKey);
sendAsyncTaskUtil.sendBackAsyncTask(taskId, asyncExportEnum.getVal(), msg, msg, null
, userEntity, SYSTEM_ERROR);
return;
}
if (ResultVOHelper.isOk(result)) {
String msg = I18nHelper.getPropertiesSource("4", null, lockKey);
sendAsyncTaskUtil.sendBackAsyncTask(taskId, asyncExportEnum.getVal(), msg, msg, result.getExtInfo()
, userEntity, COMPLETED);
} else {
String msg = result.getMsg();
sendAsyncTaskUtil.sendBackAsyncTask(taskId, asyncExportEnum.getVal(), msg, msg, null
, userEntity, RECORD_ERROR);
}
}).exceptionally(e -> {
log.error("asyncExport : Exception-3 ======================== error:{}", e);
lock.unlock();
String msg = I18nHelper.getPropertiesSource("5", null, lockKey);
//
sendAsyncTaskUtil.sendBackAsyncTask(taskId, asyncExportEnum.getVal(), msg, msg, null
, userEntity, SYSTEM_ERROR);
return null;
});
log.info("asyncExport : end ======================== lockKey:{}", StringUtil.escapeJava(lockKey));
return ResultVOHelper.builder().ok().msg(message).build();
}
@FunctionalInterface
public interface ExecuteFunction<T> {
Workbook execute() throws Exception;
}
}
主要用到的枚举类
package com.ruoyi.web.util;
import lombok.Getter;
@Getter
public enum AsyncExportEnum {
XXX_EXPORT("XXX_EXPORT"),
;
AsyncExportEnum(String value) {
this.val = value;
}
private String val;
}

407

被折叠的 条评论
为什么被折叠?



