@Async异步传递request
2023-06-27 本文已影响0人
_Rondo
前言
研发中有一些操作需要用到了异步调用,但是传递request的时候生命周期会提前结束,导致传递参数获取不到
示例
创建decorator
public class ContextDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable r) {
RequestAttributes context = RequestContextHolder.currentRequestAttributes();
return () -> {
try {
RequestContextHolder.setRequestAttributes(context);
r.run();
} finally {
RequestContextHolder.resetRequestAttributes();
}
};
}
}

配置线程池
@Configuration
public class TaskPoolConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数(默认线程数)
executor.setCorePoolSize(10);
// 最大线程数
executor.setMaxPoolSize(20);
// 缓冲队列数
executor.setQueueCapacity(200);
// 允许线程空闲时间(单位:默认为秒)
executor.setKeepAliveSeconds(60);
// 线程池名前缀
executor.setThreadNamePrefix("task-executor-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
// 增加 TaskDecorator 属性的配置
executor.setTaskDecorator(new ContextDecorator());
// 线程池对拒绝任务的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
本地用户上下文,20230809这个上下文有点问题 仅作参考
@Component
@Slf4j
public class UserContext {
@Resource
private RedisCache redisCache;
private static final String key = "u_context_";
private final ThreadLocal<Map<String, BaseUserReq>> l = new ThreadLocal<>();
private Long localId = null;
public BaseUserReq get(String taxNo) {
Map<String, BaseUserReq> map = getMap();
if (ObjectUtil.isEmpty(map.get(taxNo))) {
throw new BizException("用户信息未认证");
}
return map.get(taxNo);
}
public void set(String taxNo, BaseUserReq user) {
Map<String, BaseUserReq> map = getMap();
map.put(taxNo, user);
l.set(map);
redisCache.setCacheMap(renderKey(), map);
}
public void set(String taxNo, String username, String password) {
BaseUserReq u = new BaseUserReq();
u.setPassword(password);
u.setUsername(username);
Map<String, BaseUserReq> map = getMap();
map.put(taxNo, u);
l.set(map);
redisCache.setCacheMap(renderKey(), map);
}
public void remove() {
l.remove();
redisCache.deleteObject(renderKey());
}
private Map<String, BaseUserReq> getMap() {
Map<String, BaseUserReq> map = l.get();
if (ObjectUtil.isEmpty(map)) {
map = redisCache.getCacheMap(renderKey());
}
if (ObjectUtil.isEmpty(map)) {
map = new HashMap<>();
l.set(map);
redisCache.setCacheMap(renderKey(), map);
}
return map;
}
private String renderKey() {
//优先本地获取 同时适配三端
Long id = localId;
//session
if (ObjectUtil.isEmpty(id)) {
Authentication au = SecurityUtils.getAuthentication();
log.info("Authentication:{}", au);
if (ObjectUtil.isNotEmpty(au)) {
JSONObject jObj = JSON.parseObject(JSON.toJSONString(au.getPrincipal()));
JSONObject user = jObj.getJSONObject("user");
id = user.getLong("id");
}
//reset
resetLocalId(id);
}
//header 适配
HttpServletRequest req = ServletUtils.getRequest();
if (ObjectUtil.isEmpty(id)) {
if (ObjectUtil.isNotEmpty(req.getHeader("UserId"))) {
id = Long.valueOf(req.getHeader("UserId"));
}
//reset
resetLocalId(id);
}
log.info("renderKey id :{}", id);
return key + id;
}
private void resetLocalId(Long id) {
if (ObjectUtil.isNotEmpty(id)) {
localId = id;
}
}
}
-end-