Maison  >  Article  >  Java  >  Comment accéder aux beans de requête dans le cadre de l'exécution de tâches asynchrones ?

Comment accéder aux beans de requête dans le cadre de l'exécution de tâches asynchrones ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-31 01:54:01795parcourir

How to access request-scoped beans within asynchronous task execution?

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 :

  1. 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>
  2. 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>
  3. 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 :

  • Cette solution fonctionne à la fois pour la portée de la session et pour la portée de la requête. beans, mais pas pour les contextes de sécurité.
  • Une implémentation exécutable peut être créée et utilisée à la place de l'implémentation appelable pour la méthodeexecute().

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