如何在异步任务执行中维护请求范围
在Web应用程序中,执行需要使用bean的异步操作是很常见的与请求范围。在异步任务执行中启用请求范围可以通过实现自定义任务执行器来实现。
问题:
您拥有在 AsyncTaskExecutor 中启动处理的异步 Web 服务。但是,您需要在此处理中访问使用 @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) 注释的类。但是,您会收到异常,因为请求作用域在 SimpleAsyncTaskExecutor 中未处于活动状态。
解决方案:
要在异步任务执行中启用请求作用域,我们将实现执行以下步骤:
创建自定义任务执行器:
<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>
说明:
ContextAwarePoolExecutor 拦截提交的任务并将它们包装在 ContextAwareCallable 实例中。这些可调用对象在执行实际任务之前设置当前请求上下文,并在执行之后重置它。这确保了在异步执行期间可以访问请求范围的 bean。
注意:
以上是如何在异步任务执行中访问请求范围的 bean?的详细内容。更多信息请关注PHP中文网其他相关文章!