Maison  >  Article  >  Java  >  Comment préserver la portée de la requête lors de l'exécution de tâches asynchrones ?

Comment préserver la portée de la requête lors de l'exécution de tâches asynchrones ?

DDD
DDDoriginal
2024-10-31 21:59:02769parcourir

How to Preserve Request Scope in Asynchronous Task Execution?

Préserver la portée de la demande dans l'exécution de tâches asynchrones

Dans une application utilisant des services Web asynchrones, où le serveur répond par un accusé de réception tout en commençant le traitement asynchrone via un AsyncTaskExecutor, il devient crucial pour activer la portée de la demande. Ceci est essentiel pour accéder aux classes de bean annotées avec @Scope(WebApplicationContext.SCOPE_REQUEST).

Généralement, dans de tels scénarios, une exception se produit car la portée de la requête n'est pas active dans SimpleAsyncTaskExecutor, qui fonctionne en dehors du DispatcherServlet. . Pour résoudre ce problème, envisagez la solution suivante :

  1. Créez un exécuteur de tâches personnalisé : Définissez un exécuteur personnalisé qui étend le ThreadPoolTaskExecutor de Spring et intercepte l'exécution des tâches soumises.
  2. Encapsuler le contexte de la demande : Créez un appelable (ou exécutable) spécialisé qui utilise les informations de contexte de la demande pour définir et effacer le contexte sur le thread d'arrière-plan.
  3. Remplacer la configuration d'exécution : Remplacez la configuration de l'exécuteur par défaut pour utiliser l'exécuteur personnalisé.

Remarque : Cette approche ne prend en charge que les beans de portée Session et Demande, et non le contexte de sécurité (par exemple, Spring Security). . Pour la gestion du contexte de sécurité, des mesures distinctes doivent être mises en œuvre.

Exemple de mise en œuvre :

Exécuteur :

<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>

Appelable :

<code class="java">public class ContextAwareCallable<T> implements Callable<T> {
    private Callable<T> task;
    private RequestAttributes context;
    @Override
    public T call() throws Exception {
        if (context != null) {
            RequestContextHolder.setRequestAttributes(context);
        }
        try {
            return task.call();
        } finally {
            RequestContextHolder.resetRequestAttributes();
        }
    }
}</code>

Configuration :

<code class="java">@Configuration
public class ExecutorConfig extends AsyncConfigurerSupport {
    @Override
    @Bean
    public Executor getAsyncExecutor() {
        return new ContextAwarePoolExecutor();
    }
}</code>

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn