Frühjahr Injektion eine statische (Globale) singleton
Habe ich eine Klasse, die sieht so aus:
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
}
Es dient als eine Globale configuration-Objekt, das gesetzt werden kann auf app startup, und dann wird von Dutzenden von Klassen während des gesamten Projekts:
//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
}
}
Ich bin jetzt importieren Sie diesen code in einem Spring-Projekt, und bin gerade bei der Konfiguration meines Sprinig XML (Bohnen). Meine Vermutung ist, dass ich definieren könnte, ein einsamer Configurator
bean wie so (oder so ähnlich):
<bean id="configurator" class="com.me.myapp.Configurator" scope="singleton">
<property name="maxRange" value="30"/>
<!-- etc., for all properties -->
</bean>
So, wenn WidgetFactory#doSomething
führt, wird der Frühling bereits geladen haben die Configurator
Klasse und konfiguriert es vor der Zeit.
Ist es für mich richtig ist, um die scope="singleton"
, oder ist das egal? Bin ich mit der Einstellung der statischen Eigenschaften richtig? Gibt es etwas, was ich tun müssen, oder betrachten Sie hier? Vielen Dank im Voraus.
InformationsquelleAutor | 2013-02-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es einen Unterschied zwischen Singleton-design-Muster und Feder-singleton-Anlage. Singleton-design-Muster wird sichergestellt, dass Sie ein Objekt der Klasse definiert, die pro Class Loader. Frühjahr die singleton-Anlage (und Ansatz), im Gegensatz dazu definieren Sie eine Instanz pro Spring-Kontext.
In diesem Fall können Sie nutzen Ihre
getInstance()
Methode verwendet werden, die von Frühling zu packen Sie Ihre Objekt-Instanz:Mit Feder die
singleton
- bean-scope ist die Standardeinstellung, daher brauchen Sie nicht zu definieren.Wenn Sie verwenden möchten
configurator
als Spring-bean, die Sie haben, um es zu injizieren, die in anderen Objekten, nicht verwendengetInstance()
um es zu packen. Also in den anderen Spring-Bean mit @Autowired oder definieren Sie Referenz auf die bean durch die xml-Datei. Wenn Sie nicht reorganisieren Verwendung vonconfigurator
in anderen Klassen, es wird kein Unterschied sein, wird der Frühling instanziieren der Klasse, aber Sie werden es nach wie vor.Auch ich sah, dass Sie einen Fehler bei der Gestaltung Ihrer singleton. Ihre
getInstance()
Verfahren sollten öffentlich sein, und andere Methoden, sollten Sie nicht statisch sein. In dem Beispiel, das Sie verwendet haben, sollten Sie Nutzung des Singleton-wie diese:In diesem Fall eigentlich nur die Singleton-Klasse, ohne die Instanziierung beliebiger Objekte! Sehen wikipedia auf Singleton (Java Beispiel) für mehr Informationen auf das Singleton design pattern und wie es zu benutzen.
HINWEIS: Es lohnt sich zu wissen, und versuchen, diese zu verwenden
Configurator
als Singleton und nutzen Spring singleton-Anlage. Wenn Sie dies tun, werden die Leistungen, die Sie könnengetInstance()
MethodegetInstance()
Methode public oder können Frühjahr behandeln Sie die Tatsache, dass es privat ist?Sie brauchen es nicht (getInstance())
InformationsquelleAutor partlov
Bohnen sind singleton-standardmäßig. Sie finden diese/mehr Informationen über die spring-website.
Sollte man nicht instanziieren eines neuen Konfigurator getInstance weil es nicht beziehen sich auf die spring bean geladen und das könnte dazu führen, dass einige schwerwiegende Probleme. Sie können Draht-Bohne und dann lassen Sie es allein, es wird nicht null sein, da hast du WLAN (und wenn es dein Programm fehlgeschlagen Initialisierung).
InformationsquelleAutor Bob Flannigon
Ja, wenn Sie etwas wollen Globale singleton-scope ist die richtige option.
ein paar Dinge, die hier erwähnenswert sind :
ausdrücklich stellen Sie Ihr bean als singleton-scope.
garantieren, dass es nur eine einzige Instanz pro Feder
container. Nicht einmal zu sagen, Ihr factory-Methode ist private.
InformationsquelleAutor spiritwalker
Übrigens: dies ist nicht Thread-safe:
Während wäre dies:
(Eager Initialization)
(Lazy-Initialisierung mit volatile-Schlüsselwort)
Es hat zu tun mit der Art, wie Java reserviert Speicher und erzeugt Instanzen. Dies ist nicht atomar, sondern erfolgt in zwei Schritten und kann gestört werden durch den thread-scheduler.
Siehe auch http://regrecall.blogspot.de/2012/05/java-singleton-pattern-thread-safe.html.
InformationsquelleAutor Dennis Löhmann