美文网首页
@Async异步传递request

@Async异步传递request

作者: _Rondo | 来源:发表于2023-06-27 19:43 被阅读0次

前言

研发中有一些操作需要用到了异步调用,但是传递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();
            }
        };
    }
}
image.png

配置线程池

@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-

相关文章

网友评论

      本文标题:@Async异步传递request

      本文链接:https://www.haomeiwen.com/subject/pwenydtx.html