Comment arrêter correctement les services d'exécution avec Spring?
J'ai une application en ligne de commande qui utilise un Ressort-managed bean qui est composé d'une java ExecutorService
créé avec:
ExecutorService service = Executors.newFixedThreadPool(4);
Maintenant, je veux que mon service à l'arrêt quand mon application s'arrête, j'ai donc fait mon haricot mettre en œuvre les DisposableBean
interface et une méthode destroy tels que:
public void destroy(){
service.shutdown();
}
Alors je pourrais être tenté de faire quelque chose comme enregistrer un arrêt du crochet du Ressort du contexte. Cependant, j'ai découvert (à la dure, c'est à dire, dans une pré-version de production) que cela ne fonctionne pas: la mise à l'arrêt crochet n'est pas appelée avant la ExecutorService.shutdown()
méthode est appelée, provoquant un classique catch 22 problème (il ne me demande d'interruption, c'est à dire, si j'appuie sur Ctrl-C, alors que la demande est en cours d'exécution). Ce échappé à mes tests d'unité parce que, pour une raison quelconque, il semble bien fonctionner à partir de l'intérieur de JUnit, qui est toujours déroutant moi: qu'est-JUnit faire différemment?
La solution que j'ai trouvé jusqu'à présent est d'appeler explicitement ApplicationContext.close()
juste avant j'ai quitter ma fonction principale. Je me demandais si il y avait une meilleure solution à cette question et quelles sont les meilleures pratiques pour avoir flexibles pools de threads gérés par Spring. Aussi de ce que si mon haricot est pas directement géré par le Printemps, mais est créé par un bean géré par le Printemps? Dois-je simplement en cascade les appels à destroy()
? Ne serait-ce pas très enclins à faire des erreurs?
J'apprécie tous les commentaires, les suggestions, les lectures complémentaires, RTFMs, de recettes magiques.
Merci!
source d'informationauteur Giovanni Botta
Vous devez vous connecter pour publier un commentaire.
Êtes-vous conscient que cela:
peut être remplacé par ceci:
Le printemps contexte gère ensuite, plus directement, la fermeture de votre exécuteur testamentaire de service--et il peut facilement être réutilisé.
Envisager d'utiliser le Printemps TaskExecutor, qui peut être configuré avec un pool de threads.
http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html
Par officiel du Printemps de la documentation, lors de l'utilisation de l'annotation basée sur la configuration, pour destroyMethod champ de
@Bean
le Printemps est le comportement par défaut est automatiquement invoquer public, non-arg méthodes nomméesclose
oushutdown
lorsque le contexte de l'application est fermée.À réitérer, c'est le comportement par défaut pour annotation-driven de configuration lorsqu'un détruisent la méthode n'est pas définie de façon explicite. Si ce comportement est indésirable définition explicite de détruire méthode à une chaîne vide désactiver cette "fonctionnalité":
D'autre part, lors de l'utilisation de XML de configuration, c'est pas le comportement par défaut... pour parvenir À la parité, détruisez-la méthode peut être définie explicitement
(inferred)
. Reportez-vous à la La Destruction des rappels et Initialisation par défaut et détruire des méthodes sections dans les docs officielles pour plus de détails.