2013-03-02 4 views
3

Je voudrais implémenter une tâche asynchrone, et une page qui retourne immédiatement et démarre la tâche en arrière-plan. Cependant, la page attend à la place que la tâche d'arrière-plan se termine et retourne seulement après. Quand je visite /start cela prend 15s pour charger la page. J'utilise Spring 3.2.0. J'ai une ligne contenant <task:annotation-driven/> dans mon test-servlet.xml. La chose étrange est que même si je remplace @Async avec @Async ("this_bean_does_not_exist"), l'application fait de même (bien que je m'attendrais à une exception pour référencer un bean non existant).Spring MVC Async tâche s'exécute de manière synchrone

public interface AsyncTestService { 
    void startSlowProcess(); 
} 

@Service 
public class AsyncTestServiceImpl implements AsyncTestService { 

    @Override 
    @Async 
    public void startSlowProcess() { 
     try { 
      Thread.sleep(15000); 
     } catch (InterruptedException e) { 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

@Controller 
public class TestController { 

    @Autowired 
    AsyncTestService asyncTestService; 

    @RequestMapping("/start") 
    @ResponseBody 
    public String startSlowProcess() { 
     asyncTestService.startSlowProcess(); // It takes 15s to complete 
     return "STARTED"; // should return immediately 
    } 
} 

Répondre

3

Vous avez probablement besoin d'un executor. Essayez ceci:

<task:annotation-driven executor="myExecutor" />  
<task:executor id="myExecutor" pool-size="5"/> 

EDIT: Une autre solution possible: utiliser EnableAsync à la place (disponible depuis le printemps 3,1)

+0

J'ai essayé ça aussi avec le même résultat. –

+0

Avez-vous nettoyé votre projet avant de le tester? Pourriez-vous vérifier, si l'exécuteur est en cours d'exécution? Selon les documents (voir le lien ci-dessus), une instance d'exécuteur explicitement déclarée est requise pour que cela fonctionne. –

+0

Oui! Il me manquait EnableAsync de ma config. Je vous remercie! –

0

faire d'abord votre config .xml ressemble:

<task:scheduler id="myScheduler" pool-size="10" /> 
<task:executor id="myExecutor" pool-size="10" /> 
<task:annotation-driven executor="myExecutor" scheduler="myScheduler" proxy-target-class="true" /> 

(Oui, planificateur la taille du pool de threads count et executor est configurable)

Ou utilisez simplement la valeur par défaut:

<!-- enable task annotation to support @Async, @Scheduled, ... --> 
<task:annotation-driven /> 

Ensuite, assurez-vous que les méthodes @Async sont publiques.

Questions connexes