Comme nous le savons tous, nous avons des beans en tant que singleton par défaut dans le conteneur Spring et si nous avons une application Web basée sur le framework Spring, dans ce cas, nous devons vraiment implémenter le modèle de conception Singleton pour contenir des données globales plutôt que de simplement créer un bean à travers le printemps .
Veuillez me supporter si je ne suis pas en mesure d'expliquer ce que je voulais vraiment demander.
la source
La portée singleton dans spring signifie une seule instance dans un contexte Spring.
Le conteneur Spring renvoie simplement la même instance encore et encore pour les appels suivants pour obtenir le bean.
Et spring ne dérange pas si la classe du bean est codée comme singleton ou non, en fait si la classe est codée comme singleton dont le constructeur est privé, Spring utilise BeanUtils.instantiateClass (javadoc ici ) pour définir le constructeur sur accessible et invoquer il.
Alternativement, nous pouvons utiliser un attribut de méthode d'usine dans la définition de bean comme ceci
la source
Prenons l'exemple le plus simple: vous avez une application et vous utilisez simplement le chargeur de classe par défaut. Vous avez une classe qui, pour une raison quelconque, vous décidez qu'elle ne doit pas avoir plus d'une instance dans l'application. (Pensez à un scénario où plusieurs personnes travaillent sur des pièces de l'application).
Si vous n'utilisez pas le framework Spring, le modèle Singleton garantit qu'il n'y aura pas plus d'une instance d'une classe dans votre application. C'est parce que vous ne pouvez pas instancier des instances de la classe en faisant 'new' car le constructeur est privé. La seule façon d'obtenir une instance de la classe est d'appeler une méthode statique de la classe (généralement appelée «getInstance») qui renvoie toujours la même instance.
Dire que vous utilisez le framework Spring dans votre application signifie simplement qu'en plus des moyens habituels d'obtenir une instance de la classe (méthodes nouvelles ou statiques qui renvoient une instance de la classe), vous pouvez également demander à Spring de vous obtenir une instance de cette classe et Spring garantira que chaque fois que vous lui demanderez une instance de cette classe, elle retournera toujours la même instance, même si vous n'avez pas écrit la classe en utilisant le modèle Singleton. En d'autres termes, même si la classe a un constructeur public, si vous demandez toujours à Spring une instance de cette classe, Spring n'appellera ce constructeur qu'une seule fois pendant la durée de vie de votre application.
Normalement, si vous utilisez Spring, vous ne devez utiliser Spring que pour créer des instances, et vous pouvez avoir un constructeur public pour la classe. Mais si votre constructeur n'est pas privé, vous n'empêchez vraiment personne de créer directement de nouvelles instances de la classe, en contournant Spring.
Si vous voulez vraiment une seule instance de la classe, même si vous utilisez Spring dans votre application et que vous définissez la classe dans Spring comme un singleton, le seul moyen de garantir cela est également d'implémenter la classe à l'aide du modèle Singleton. Cela garantit qu'il y aura une seule instance, que les gens utilisent Spring pour obtenir une instance ou contourner Spring.
la source
Je trouve " par contenant par haricot" difficile à appréhender . Je dirais " un bean par id de haricot dans un conteneur ". Prenons un exemple pour le comprendre. Nous avons un exemple de classe de haricots. J'ai défini deux beans de cette classe dans la définition de bean, comme:
Ainsi, chaque fois que j'essaye d'obtenir le bean avec l'id "id1", le conteneur de ressort créera un bean, le mettra en cache et retournera le même bean où jamais référencé avec id1. Si j'essaie de l'obtenir avec id7, un autre bean sera créé à partir de la classe Sample, il sera mis en cache et retourné chaque fois que vous l'avez référencé avec id7.
Ceci est peu probable avec le modèle Singleton. Dans le modèle Singlton, un objet par chargeur de classe est toujours créé. Cependant, au printemps, faire de la portée comme Singleton n'empêche pas le conteneur de créer de nombreuses instances à partir de cette classe. Cela restreint simplement la création d'un nouvel objet pour le même ID, retournant un objet précédemment créé lorsqu'un objet est demandé pour le même ID . Référence
la source
La portée Singleton dans Spring signifie que ce bean ne sera instancié qu'une seule fois par Spring. Contrairement à la portée du prototype (nouvelle instance à chaque fois), la portée de la requête (une fois par requête), la portée de la session (une fois par session HTTP).
La portée Singleton n'a techniquement rien à voir avec le modèle de conception singleton. Vous n'avez pas besoin d'implémenter vos beans en tant que singletons pour qu'ils soient placés dans la portée singleton.
la source
Les beans singleton dans Spring et les classes basées sur le modèle de conception Singleton sont assez différents.
Le modèle Singleton garantit qu'une et une seule instance d'une classe particulière sera jamais créée par chargeur de classe, alors que la portée d'un bean singleton Spring est décrite comme «par conteneur par bean». La portée Singleton dans Spring signifie que ce bean ne sera instancié qu'une seule fois par Spring. Le conteneur Spring renvoie simplement la même instance encore et encore pour les appels suivants pour obtenir le bean.
la source
Il y a une différence très fondamentale entre les deux. Dans le cas du modèle de conception Singleton, une seule instance d'une classe sera créée par classLoader alors que ce n'est pas le cas avec Spring singleton, car dans la dernière instance de bean partagé pour l'ID donné par conteneur IoC est créée.
Par exemple, si j'ai une classe avec le nom "SpringTest" et que mon fichier XML ressemble à ceci: -
Alors maintenant, dans la classe principale, si vous vérifiez la référence des deux ci-dessus, il retournera false comme selon la documentation de Spring: -
Donc, comme dans notre cas, les classes sont les mêmes mais les identifiants que nous avons fournis sont différents, ce qui entraîne la création de deux instances différentes.
la source
"singleton" au printemps utilise l'instance get bean factory, puis la cache; quel modèle de conception de singleton est strictement, l'instance ne peut être récupérée qu'à partir de la méthode get statique, et l'objet ne peut jamais être instancié publiquement.
la source
EX: "par contenant par grain".
JAVA SINGLETON:
la source
Le haricot singleton de printemps est décrit comme «par contenant par haricot». La portée Singleton dans Spring signifie que le même objet au même emplacement mémoire sera renvoyé au même identifiant de bean. Si l'on crée plusieurs beans de différents identifiants de la même classe, le conteneur renverra différents objets à différents identifiants. C'est comme un mappage de valeur de clé où la clé est l'id du bean et la valeur est l'objet du bean dans un conteneur à ressort. Where as Singleton pattern garantit qu'une et une seule instance d'une classe particulière sera jamais créée par chargeur de classe.
la source
Toutes les réponses, du moins jusqu'à présent, se concentrent sur l'explication de la différence entre le modèle de conception et Spring singleton et ne répondent pas à votre question réelle: un modèle de conception Singleton devrait-il être utilisé ou un haricot singleton Spring? Qu'est-ce qui est mieux?
Avant de répondre, permettez-moi de dire que vous pouvez faire les deux. Vous pouvez implémenter le bean en tant que modèle de conception Singleton et utiliser Spring pour l'injecter dans les classes clientes en tant que bean singleton Spring.
Maintenant, la réponse à la question est simple: n'utilisez pas le modèle de conception Singleton!
Utilisez le bean singleton de Spring implémenté en tant que classe avec un constructeur public.
Pourquoi? Parce que le modèle de conception Singleton est considéré comme un anti-modèle. Surtout parce que cela complique les tests. (Et si vous n'utilisez pas Spring pour l'injecter, toutes les classes qui utilisent le singleton y sont maintenant étroitement liées), et vous ne pouvez pas le remplacer ou l'étendre. On peut google "Anti-pattern Singleton" pour obtenir plus d'informations à ce sujet, par exemple anti-pattern Singleton
Utiliser Spring singleton est la voie à suivre (avec un bean singleton implémenté NON comme un modèle de conception Singleton, mais plutôt avec un constructeur public) afin que le bean Spring singleton puisse facilement être testé et les classes qui l'utilisent ne lui sont pas étroitement couplées , mais plutôt, Spring injecte le singleton (en tant qu'interface) dans tous les beans qui en ont besoin, et le bean singleton peut être remplacé à tout moment par une autre implémentation sans affecter les classes clientes qui l'utilisent.
la source