Comment conserver la portée de la demande dans l'exécution de tâches asynchrones
Dans les applications Web, il est courant d'effectuer des opérations asynchrones qui nécessitent l'utilisation de beans avec portée de la demande. L'activation de la portée des requêtes dans l'exécution de tâches asynchrones peut être obtenue en implémentant un exécuteur de tâches personnalisé.
Problème :
Vous disposez de services Web asynchrones qui lancent le traitement dans un AsyncTaskExecutor. Cependant, vous devez accéder aux classes annotées avec @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) dans ce traitement. Cependant, vous recevez une exception car la portée de la requête n'est pas active dans SimpleAsyncTaskExecutor.
Solution :
Pour activer la portée de la requête dans l'exécution de la tâche asynchrone, nous implémenterons les étapes suivantes :
Créer un TaskExecutor personnalisé :
<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>
Implémenter un exécuteur contextuel Appelable :
<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>
Configurer le TaskExecutor personnalisé :
<code class="java">@Configuration public class ExecutorConfig extends AsyncConfigurerSupport { @Override @Bean public Executor getAsyncExecutor() { return new ContextAwarePoolExecutor(); } }</code>
Explication :
Le ContextAwarePoolExecutor intercepte les tâches soumises et les enveloppe dans des instances ContextAwareCallable. Ces callables définissent le contexte de requête actuel avant d'exécuter la tâche réelle et le réinitialisent ensuite. Cela garantit que les beans de portée requête sont accessibles pendant l'exécution asynchrone.
Remarque :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!