非同期タスクでのリクエスト スコープの維持
Web アプリケーションでは、リクエストを受信した後に非同期タスクを実行するのが一般的です。ただし、これらのタスクが @Scope(value = WebApplicationContext.SCOPE_REQUEST) アノテーションが付けられたオブジェクトなど、リクエスト固有のオブジェクトに確実にアクセスできるようにするのは困難な場合があります。
非ブロック的な方法でリクエストを処理する場合、デフォルトの SimpleAsyncTaskExecutor はリクエスト スレッドのスコープにアクセスできないため、「現在のスレッドではスコープ 'request' がアクティブではありません。」のような例外が発生します。
この問題に対処するために、カスタム 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>
このカスタム エグゼキュータを利用することで、非同期タスクはリクエストにシームレスにアクセスできます。スコープ付きオブジェクト。デフォルトの SimpleAsyncTaskExecutor.
の制限を克服します。以上が非同期タスクでリクエストのスコープを維持するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。