Guice eager/lazy singleton-Instanzen

Ich habe einige Schwierigkeiten zu verstehen, wie Guice die singleton-Instanzen funktioniert. Ich habe gelesen, die verfügbare Dokumentation (hier - http://code.google.com/p/google-guice/wiki/Scopes ), aber ich kann immer noch nicht herausfinden, einige Dinge:

1) ich habe Guice integriert mit Tomcat, und ich habe einige Bindungen in einem ServletModule:

bind(MyServlet.class).asEagerSingleton();
serve("myUrl").with(MyServlet.class);
serve("myOtherUrl").with(MyOtherServlet.class);

(wo MyOtherServlet Klasse hat ein @Singleton-annotation oben)
Meine Absicht hier war es, zwei servlets, wo man ist gespannt instanziiert, während der andere nicht. Aber es scheint, wie das "dienen... mit..." - Zeile automatisch erzeugt servlets Objekte, auch wenn diese Klasse nicht gebunden ist, als ein eifriger singleton.
Der link, den ich angehängt oben erwähnt, Unterschied zwischen Guice unter der Bühne.Entwicklung und Bühne.Produktion - jedoch ist dies immer noch passiert, selbst wenn ich explizit verwendet der Bühne.Entwicklung (das ist der Standard sowieso).
Gibt es eine Möglichkeit, dies zu vermeiden?

2) (Fortsetzung 1) Versuchen, um sicherzustellen, dass MyServlet instanziiert erste, obwohl alle servlets instanziieren gespannt jetzt, ich habe geändert, die Reihenfolge der Module (und verbindliche Aussagen) bei der Erstellung eines Injektors, so dass die Bindung für MyServlet wird zuerst angezeigt. Allerdings fand ich, dass es noch instanziiert später als einige andere Bindungen (nicht-servlet Klassen), die waren von der form:

bind(MyInterface.class).to(MyClass.class).asEagerSingleton()

obwohl diese anderen Bindungen erschien später in den Modulen/Bindungen um.
Ich habe hingeschaut, und festgestellt, dass Guice einfach instanziiert eifrig singletons, die gebunden waren, die durch die form der "Bindung... zur... asEagerSingleton()" vor, der "bind... asEagerSingleton()", und so habe ich es gelöst durch ändern der Zeile:
bind(MyServlet.class).asEagerSingleton();
in:
bind(MyServletDummyInterface.class).zu(MyServlet.class).asEagerSingleton()

... und das hat tatsächlich funktioniert. Trotzdem würde ich eher vermeiden, dass ein dummy-interface, nur um dieses Problem zu lösen, so war ich Frage mich, ob jemand hatte eine bessere Lösung für dieses..?

3) ich habe zwei Guice-Module - eine ServletModule und eine AbstractModule.
Die ServletModule configureServlets() hat die folgenden verbindlich in:

serve("aUrl").with(SomeServlet.class);

Den AbstractModule configure() hat die folgenden Bindungen:

bind(SomeImpl.class).asEagerSingleton();
bind(SomeInterface.class).to(SomeImpl.class).in(Singleton.class);

Darüber hinaus Die SomeServlet Klasse hat ein eingefügtes Feld vom Typ SomeInterface, und hat ein @Singleton-annotation auf der Oberseite der Klasse.

Nun würde man erwarten, dass bei der Erstellung eines Injektors, der SomeImpl Klasse bekommen wird instanziiert, und die gleiche Instanz injiziert werden, in der SomeServlet Instanz. Wie bereits erwähnt, servlets, begrenzt mit einer "dienen... mit..." - Aussage auch zu bekommen scheinen eifrig instanziiert, aber entweder Weg, es sollte doch nur ein SomeImpl-Objekt instanziiert. Aber aus irgendeinem Grund, habe ich zwei SomeImpl Objekte instanziiert, wenn dies zu tun.
Zu bekommen, um es, ich mischte die zwei Zeilen in der configure() ein wenig, und anstelle des oben hatte ich dort die folgenden Zeilen:

bind(SomeImpl.class).in(Singleton.class)
bind(SomeInterface.class).to(SomeImpl.class).asEagerSingleton();

und dann funktionierte es gut, und ich habe nur eine Instanz von SomeImpl instanziiert. Ich weiß nicht wirklich, warum sollte der Schalter egal - ich kann sehen, wie die letztere Art ist "besser", aber ich würde erwarten, dass beide ordnungsgemäß funktionieren, so dass ich Frage mich nur, ob ich immer bin etwas falsch hier..?

Sorry wegen der Länge,

Vielen Dank für die Hilfe!

InformationsquelleAutor user976850 | 2011-11-08
Schreibe einen Kommentar