非同期タスク実行でリクエスト スコープを維持する方法
Web アプリケーションでは、Bean の使用を必要とする非同期操作を実行するのが一般的ですリクエストスコープ付き。非同期タスク実行でリクエスト スコープを有効にするには、カスタム タスク エグゼキューターを実装します。
問題:
AsyncTaskExecutor で処理を開始する非同期 Web サービスがあります。ただし、この処理内で @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) アノテーションが付けられたクラスにアクセスする必要があります。ただし、SimpleAsyncTaskExecutor でリクエスト スコープがアクティブではないため、例外が発生します。
解決策:
非同期タスクの実行でリクエスト スコープを有効にするには、以下を実装します。次の手順:
カスタム TaskExecutor の作成:
<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>
カスタム TaskExecutor の構成:
<code class="java">@Configuration public class ExecutorConfig extends AsyncConfigurerSupport { @Override @Bean public Executor getAsyncExecutor() { return new ContextAwarePoolExecutor(); } }</code>
:
ContextAwarePoolExecutor は、送信されたタスクをインターセプトし、ContextAwareCallable インスタンスにラップします。これらの呼び出し可能オブジェクトは、実際のタスクを実行する前に現在のリクエスト コンテキストを設定し、その後リセットします。これにより、非同期実行中にリクエスト スコープの Bean に確実にアクセスできるようになります。
注:
以上が非同期タスク実行内でリクエストスコープの Bean にアクセスするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。