Printemps de l'injection d'un statique (global) singleton
J'ai une classe qui ressemble à ceci:
public class Configurator {
private static Configurator INSTANCE = null;
private int maxRange = 1;
//many other properties; each property has a default value
private static synchronized Configurator getInstance() {
if(INSTANCE == null)
return new Configurator();
return INSTANCE;
}
public static int getMaxRange() {
getInstance().maxRange;
}
public static void setMaxRange(int range) {
getInstance().maxRange = range;
}
//Getters and setters for all properties follow this pattern
}
Elle sert à la configuration globale de l'objet qui peut être mis sur l'application de démarrage, puis est utilisé par des dizaines de classes tout au long du projet:
//Called at app startup to configure everything
public class AppRunner {
Configurator.setMaxRange(30);
}
//Example of Configurator being used by another class
public class WidgetFactory {
public void doSomething() {
if(Configurator.getMaxRange() < 50)
//do A
else
//do B
}
}
Je suis maintenant l'importation de ce code dans un projet pour le Printemps, et je suis en train de configurer mon Sprinig XML (haricots). Ma conjecture est que je pourrais définir un seul Configurator
bean comme si (ou quelque chose de similaire):
<bean id="configurator" class="com.me.myapp.Configurator" scope="singleton">
<property name="maxRange" value="30"/>
<!-- etc., for all properties -->
</bean>
De cette façon, lorsque WidgetFactory#doSomething
exécute, le Printemps sera déjà chargé le Configurator
classe et configuré à l'avance.
Est-elle corriger pour moi de mettre la scope="singleton"
, ou ne présente pas d'importance? Suis-je en définissant les propriétés statiques correctement? Est-il autre chose que je dois faire ou envisager ici? Merci à l'avance.
OriginalL'auteur | 2013-02-01
Vous devez vous connecter pour publier un commentaire.
Il y a une certaine différence entre Singleton comme un modèle de conception et le Printemps singleton installation. Singleton comme un modèle de conception permettra d'assurer que vous avez un objet de la classe définie par le Chargeur de classes. Printemps singleton installation (et à l'approche), en revanche, sera de définir une instance par le Printemps Contexte.
Dans ce cas, vous pouvez utiliser votre
getInstance()
méthode à utiliser d'ici le Printemps pour se saisir de votre instance de l'objet:Avec le Printemps, la
singleton
bean portée est la valeur par défaut donc vous n'avez pas besoin de la définir.Si vous souhaitez utiliser
configurator
comme un Printemps bean, vous aurez à injecter dans d'autres objets, ne pas utilisergetInstance()
pour l'attraper. Donc, en d'autres beans Spring utiliser @Autocâblés ou définir une référence à la fève par fichier xml. Si vous n'avez pas de réorganiser l'utilisation deconfigurator
dans d'autres classes, il n'y aura pas de différence, le Printemps va instancier ta classe, mais vous allez l'utiliser comme avant.Aussi, j'ai vu que vous avez une erreur dans la conception de votre singleton. Votre
getInstance()
méthode doit être publique, et d'autres méthodes ne doit pas être statique. Dans l'exemple que vous avez utilisé, vous devez utiliser un Singleton comme ceci:Dans ce cas, vous en fait tout simplement utiliser la classe Singleton, sans l'instanciation des objets! Voir wikipédia sur Singleton (avec exemple Java) pour plus d'informations sur le modèle de conception Singleton et comment l'utiliser.
REMARQUE: Il est utile de connaître et d'essayer d'utiliser
Configurator
comme un Singleton et de faire usage du Printemps singleton installation. Si vous ne ce seront les avantages que vous pouvezgetInstance()
méthodegetInstance()
méthode, ou peut-Printemps gérer le fait que c'est le privé?Vous n'en avez pas besoin (getInstance())
OriginalL'auteur partlov
Les haricots sont singleton par défaut. Vous pouvez trouver cette/plus d'informations via le site web de spring.
Vous ne devriez pas instancier un nouveau Configurateur en getInstance car il n'a rien à voir avec le ressort du haricot et qui pourrait causer de sérieux problèmes. Vous pouvez le fil de cette fève, puis le laisser seul, il n'est pas null parce que vous avez câblé (et si c'est votre programme échec de l'initialisation).
OriginalL'auteur Bob Flannigon
Oui, si vous voulez quelque chose de global, portée singleton est la bonne option.
quelques choses à mentionner ici sont :
définir explicitement votre bean portée singleton.
garantir qu'il n'existe qu'une seule instance par le Printemps
le conteneur. Même pas de dire, votre méthode de fabrique est privé.
OriginalL'auteur spiritwalker
Par la voie: ce n'est pas Thread-safe:
Alors que ce serait:
(Désireux D'Initialisation)
(Initialisation avec le mot clé volatile)
Il a à voir avec la façon dont Java alloue de la Mémoire et de créer des instances. Ce n'est pas atomique, mais le fait en deux étapes et peut être entravé par le planificateur de threads.
Voir aussi http://regrecall.blogspot.de/2012/05/java-singleton-pattern-thread-safe.html.
OriginalL'auteur Dennis Löhmann