带有请求范围Bean的Spring executor服务无法正常运行

时间:2018-11-16 10:26:51

标签: java spring threadpool executorservice requestscope

已经提出了这个问题,但是我们无法使solution正常工作。


我们有一个类可以用作用户详细信息类。我们已经在spring config下的request-scope bean中创建了它。

    @Bean
    @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public UserContext userContext() {
        return new UserContext();
    }

我们的执行器配置-

@Override
@Bean
public AsyncTaskExecutor getAsyncExecutor() {
    ThreadPoolTaskExecutor poolExecutor = new ThreadPoolTaskExecutor();
    poolExecutor.setTaskDecorator(new ContextCopyingDecorator());
    poolExecutor.initialize();
    return poolExecutor;
}

还有任务装饰器-

public class ContextCopyingDecorator implements TaskDecorator {
private static final Logger logger = LoggerFactory.getLogger(ContextCopyingDecorator.class);

@Nonnull
@Override
public Runnable decorate(@Nonnull Runnable runnable) {
    logger.info("Decorating context: ");

    RequestAttributes context =
            RequestContextHolder.currentRequestAttributes();
    Map<String, String> contextMap = MDC.getCopyOfContextMap();

    return () -> {
        try {
            RequestContextHolder.setRequestAttributes(context);
            RequestContextHolder.setRequestAttributes(context, true);
            MDC.setContextMap(contextMap);

            logger.info("Context: {}", context);
            logger.info("MDC: {}", contextMap);
            runnable.run();
        } finally {
            MDC.clear();
            RequestContextHolder.resetRequestAttributes();
        }
    };
}

}

但是,一旦执行进入其他线程,userContext中的值就会继续出现null。我们尝试了多种方法,例如InheritableThreadLocal来引入自定义会话inherited-scope和上面的任务装饰器,但到目前为止没有成功。

有没有办法传递这些数据?我们错过了什么吗? 因为最终,我们可能不得不使用ThreadLocal来处理此问题,这并不是一个很好的解决方案,正如不同帖子所述。

0 个答案:

没有答案