在非同步任務中維護請求範圍
在 Web 應用程式中,收到請求後執行非同步任務是很常見的。然而,確保這些任務能夠存取特定於請求的對象,例如那些用 @Scope(value = WebApplicationContext.SCOPE_REQUEST) 註解的對象,可能具有挑戰性。
以非阻塞方式處理請求時,預設 SimpleAsyncTaskExecutor 無權存取請求執行緒的作用域,從而導致諸如「作用域『請求』對於當前執行緒無效」之類的例外狀況。
要解決此問題,可以建立自訂 ContextAwarePoolExecutor。該執行器將請求上下文資訊與任務一起存儲,並利用 ContextAwareCallable 設定和清除後台執行緒所需的上下文。
自訂執行器實作:
<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>
以上是如何維護非同步任務中的請求範圍?的詳細內容。更多資訊請關注PHP中文網其他相關文章!