在异步任务执行中启用请求范围
问题:
异步 Web 服务需要在异步处理中访问请求范围的 bean,特别是那些用 @Scope(value = WebApplicationContext.SCOPE_REQUEST) 注释的 bean。但是,SimpleAsyncTaskExecutor 不会保留线程绑定的请求属性,从而导致异常。
解决方案:
为了在异步任务执行中启用请求作用域,创建了一个自定义的 TaskPoolExecutor以及一个特殊的 Callable,用于存储和清除后台线程的请求上下文。
实现:
自定义执行器:
<code class="java">public class ContextAwarePoolExecutor extends ThreadPoolTaskExecutor { @Override public <T> Future<T> submit(Callable<T> task) { return super.submit(new ContextAwareCallable(task, RequestContextHolder.currentRequestAttributes())); } }</code>
上下文感知可调用:
<code class="java">public class ContextAwareCallable<T> implements Callable<T> { private Callable<T> task; private RequestAttributes context; public ContextAwareCallable(Callable<T> task, RequestAttributes context) { this.task = task; this.context = context; } @Override public T call() throws Exception { if (context != null) { RequestContextHolder.setRequestAttributes(context); } try { return task.call(); } finally { RequestContextHolder.resetRequestAttributes(); } } }</code>
配置覆盖:
<code class="java">@Configuration public class ExecutorConfig extends AsyncConfigurerSupport { @Override @Bean public Executor getAsyncExecutor() { return new ContextAwarePoolExecutor(); } }</code>
用法:
<code class="java">taskExecutor.execute(new ContextAwareCallable(new Runnable() { @Override public void run() { asyncRequest(request); } }), RequestContextHolder.currentRequestAttributes());</code>
注意:
以上是如何在异步任务执行中启用请求范围?的详细内容。更多信息请关注PHP中文网其他相关文章!