Obtenir une nouvelle instance du ressort de haricot
J'ai une interface appelée MyInterface
. La classe qui implémente MyInterface
(appelons cela MyImplClass
) met également en œuvre la Runnable
interface donc je peux l'utiliser pour instancier les threads. C'est mon code maintenant.
for (OtherClass obj : someList) {
MyInterface myInter = new MyImplClass(obj);
Thread t = new Thread(myInter);
t.start();
}
Ce que je veux faire est de déclarer la mise en œuvre de la classe dans mon ApplicationContext.xml et obtenir une nouvelle instance à chaque itération. Donc mon code devrait ressembler à quelque chose comme ceci:
for (OtherClass obj : someList) {
MyInterface myInter = //getting the implementation from elsewhere
Thread t = new Thread(myInter);
t.start();
}
Je veux encore garder le Cio modèle si possible.
Comment puis-je le faire?
Grâce
avez-vous essayé ?
jetez aussi un oeil à la réponse à cette question. stackoverflow.com/questions/812415/...
Ce que je comprends -
disons pour l'instant que sa en raison de la sécurité des threads. Le thread appelle une ressource web avec des paramètres en fonction de l'obj donné dans le constructeur, donc oui, - j'ai besoin de plusieurs instances d'une classe définie par l'
Oublier le dernier commentaire. Nous allons expliquer les choses plus loin: Apatrides objets de printemps sont toujours partagée et traités en tant que singleton et créé une fois dans le contexte de conteneur IoC. Stateful sont traités en tant que prototype de sorte l'objet sera créé à chaque fois il demande par conteneur IoC.Donc, en environnement Multithread vous avez besoin à la fois de type. En tant que source de données de l'objet instancié qu'une seule fois par l'application et partagées par tous les objets de sorte qu'il est nécessaire de Singleton et le Prototype comme vos objets POJO.
MyClass myClass = applicationContext.getBean("myClass");
jetez aussi un oeil à la réponse à cette question. stackoverflow.com/questions/812415/...
Ce que je comprends -
ApplicationContext.getBean
n'est pas du Cio. aussi, le lien que vous avez proposé suggère une instance unique solution. pour ce que je peux utiliser Injecter annotaion - ce qui est plus général (pas de printemps à charge).disons pour l'instant que sa en raison de la sécurité des threads. Le thread appelle une ressource web avec des paramètres en fonction de l'obj donné dans le constructeur, donc oui, - j'ai besoin de plusieurs instances d'une classe définie par l'
Oublier le dernier commentaire. Nous allons expliquer les choses plus loin: Apatrides objets de printemps sont toujours partagée et traités en tant que singleton et créé une fois dans le contexte de conteneur IoC. Stateful sont traités en tant que prototype de sorte l'objet sera créé à chaque fois il demande par conteneur IoC.Donc, en environnement Multithread vous avez besoin à la fois de type. En tant que source de données de l'objet instancié qu'une seule fois par l'application et partagées par tous les objets de sorte qu'il est nécessaire de Singleton et le Prototype comme vos objets POJO.
OriginalL'auteur Mr T. | 2015-04-07
Vous devez vous connecter pour publier un commentaire.
Vous pouvez essayer le modèle de fabrique avec le printemps portée prototype comme ci-dessous. Définir un Résumé de l'Usine de la Classe qui vous donnera
MyInterface
objetEnsuite définir le Printemps bean.xml fichier comme ci-dessous. Veuillez noter
myinterface
bean est défini comme prototype ( Donc il sera toujours vous donner un exemple).Puis de définir l'interface factorybean avec l'usine nom de la méthode.
Maintenant, vous pouvez appeler
myinterfaceFactory
pour obtenir une nouvelle instance.OriginalL'auteur Himanshu Ahire
Garder le printemps fichier de configuration, beans.xml dans la racine du classpath.
Faire scope=prototype, se traduira par différentes instances de haricot pour chaque invocation de méthode getBean.
beans.xml
Manière similaire, si vous voulez Printemps de retourner la même haricot exemple à chaque fois que l'on est nécessaire, vous devez déclarer le bean de la portée de l'attribut à singleton.
Une fois le conteneur IoC est initialisé, vous pouvez récupérer vos beans Spring. Mais assurez-vous que vous ne le dessous seulement d'initialisation qu'une seule fois.
Ensuite, vous pouvez changer votre code comme ci-dessous.
Solution par @Himorithm fonctionnera très bien. Passez par docs.printemps.io/printemps/docs/4.1.6.PRESSE/...
OriginalL'auteur Albin
Étant donné le contexte que vous avez fourni dans votre commentaire à moi, je vous suggère de ne pas le
MyImplClass
les instances créées par le Printemps. Ayant de ce fait un prototype de l'objet instancié par le Printemps ne fournit aucune prestation de ce que je peux dire.De la meilleure façon, à mon avis, de garder avec le Cio modèle serait ici au lieu d'utiliser un Printemps réussi Usine qui produit des instances de
MyImplClass
. Quelque chose le long des lignes de ce:Selon les besoins d'utilisation, vous pouvez modifier cette usine de l'interface à retour
MyImplClass
, ou ajouter un peu de logique pour revenir à une mise en œuvre différente deMyInterface
.J'ai tendance à penser que les Usines et les Cio/DI fonctionner assez bien, et votre cas d'utilisation est un assez bon exemple de cela.
OriginalL'auteur nicholas.hauschild
La Première Note 1
Au lieu de créer et de départ fils par la main, je vous suggère d'utiliser un pool de threads que de l'extérieur configuré, de sorte que vous pouvez gérer le nombre de threads créés. Si la taille de
someList
est de 1000, en créant ainsi de nombreux threads est inefficace. Il est mieux d'utiliser un exécuteur testamentaire soutenu par un pool de threads. Spring fournit des implémentations qui peut être utilisé comme beans spring configuré avec letask
espace de noms, quelque chose comme ceci:queue-capacity
est la taille maximale du pool de threads. Si cette taille est dépassée, le thread courant sera exécuter la tâche supplémentaire, bloquant ainsi la boucle jusqu'à ce qu'un autre thread est libéré (rejection-policy="CALLER_RUNS"
). Voir latask:executor
de la documentation, ou de définir touteThreadPoolExecutor
(printemps ou jdk-simultanées) avec votre propre configuration.La Première Note 2
Si le seul état que vous l'intention de le stocker dans
MyClassImpl
est l'élément de la liste, vous pouvez oublier le reste de l'explication ci-dessous (sauf pour le pool de threads trucs), et d'utiliser directement un singleton bean : supprimer leRunnable
de l'interface et de ses non-argrun()
méthode, ajouter unrun(OtherClass obj)
méthode et de faire quelque chose comme ceci:Si vous prévoyez de stocker de l'état à l'intérieur MyClassImpl lors de l'exécution de
run()
(autres que les traités de l'objet), aller sur la lecture. Mais vous pourrez toujours utiliser lerun(OtherClass obj)
méthode au lieu de n-argsrun()
.L'idée de base est d'obtenir un objet différent pour chaque thread en cours d'exécution, basée sur une sorte de modèle ou prototype défini comme un printemps bean. Afin de réaliser cela, il suffit de définir le haricot que vous voulez d'abord passer à chaque thread comme un proxy qui distribue à une instance qui est lié à la thread en cours d'exécution. Cela signifie que la même instance de la tâche est injecté dans chaque thread, et au cours de l'exécution du thread, la véritable tâche sur laquelle vous appelez des méthodes est lié au thread courant.
Programme principal
Puisque vous êtes en utilisant les éléments de la liste à faire de votre entreprise, vous passerez chaque élément à son propriétaire de la tâche.
Nous supposons que
Program
est un ressort de haricots, ainsi que les dépendances peuvent être injectées. SiProgram
n'est pas un printemps bean, vous aurez besoin d'obtenir le printemps ApplicationContext de quelque part, alors autowireProgram
(c'est à dire injecter des dépendances trouvé dans l'ApplicationContext, basé sur les annotations). Quelque chose comme ceci (dans le constructeur) :Définir la tâche
taskTarget
est là que vous définissez dans votre entreprise. Ce bean est défini comme un prototype, comme une nouvelle instance sera attribuée à chaque thread. Grâce à cela, vous pouvez même stocker l'état qui dépend de larun()
paramètre. Ce bean est jamais utilisé directement par l'application (doncautowire-candidate="false"
), mais il est utilisé à travers letask
bean. DansexecuteConcurrently()
ci-dessus, la lignetask.run(obj)
sera effectivement distribué sur l'un des prototypetaskTarget
qui a été créé par le proxy.OriginalL'auteur Gaetan
Si vous pouvez déterminer au moment de l'exécution qui
MyImplClass
l'instance à utiliser, vous pourriez la liste de toutes les implémentations de haricots dans votre contexte xml et@Autowire
d'un tableau de typeMyInterface
pour obtenir tousMyInterface
réalisateurs.Le suivant dans le contexte xml:
Puis une décélération
entraînera
allInterfaceBeans
contenant à la fois des haricots défini ci-dessus.Si vous voulait la logique pour déterminer quelle application utiliser pour être fait à la durée d'injection, vous pouvez toujours
@Autowire
une méthode de définitionsetAllInterfaceBeans(MyInterface[] allInterfaceBeans);
.OriginalL'auteur Ben Kern
D'abord et avant tout, nous savons tous que, par défaut, printemps conteneur créer bean dans le singleton mode (si vous n'avez pas spécifier explicitement le champ d'application). Comme son nom l'indique, singleton garantie que chaque fois que vous appelez le haricot, il vous donnera la même instance. Néanmoins, il y a peu de différences entre singleton au printemps avec l'un singleton que mentionné par le GoF. Au Printemps, l'instance créée sera limité au conteneur (pas de JVM que nous avons trouvé dans le GoF).
En outre, au printemps, vous pouvez définir deux bean instances du même type mais avec des noms différents et ils seront deux instances différentes créé sur le tas. Mais à chaque fois que vous faites référence à l'un de ces grains par le nom (ref= dans un haricot définition ou getBean sur le appContext), vous obtenez le même objet à chaque fois. C'est évidemment différente de l'pattern singleton, mais similaire dans le concept de toute façon.
Généralement parlant, il y a des implications de l'utilisation d'un singleton dans une application multi-thread (Printemps singleton ou réelle singleton). Tout état qui vous garder sur ces objets doivent tenir compte du fait que plusieurs threads. Généralement, tout état qui existe sera défini lors de l'instanciation par l'intermédiaire d'un setter ou argument du constructeur. Cette catégorie de Printemps bean a de sens pour longue durée de vie des objets, thread-safe objets. Si vous voulez quelque chose de thread spécifique et toujours envie de printemps pour créer l'objet, puis prototype champ d'application les œuvres.
OriginalL'auteur MCHAppy