我在理解Guice的單例實例如何工作時遇到了一些麻煩。我已閱讀可用的文檔(這裏 - http://code.google.com/p/google-guice/wiki/Scopes),但我仍然無法弄清楚一些事情:Guice渴望/懶惰的單例實例
1)我已經集成了Guice和Tomcat,並且我在ServletModule中設置了一些綁定:
bind(MyServlet.class).asEagerSingleton();
serve("myUrl").with(MyServlet.class);
serve("myOtherUrl").with(MyOtherServlet.class);
(其中MyOtherServlet類有它上面的@Singleton註解) 我在這裏的目的是爲了有兩個servlet,其中一個是熱切實例,而另一個則不是。然而,似乎「serve ... with ...」這一行自動實例化servlet對象,即使該類沒有被綁定爲一個急切的單例。 我上面提到的鏈接提到了在Stage.Development和Stage.Production下運行的Guice之間的區別 - 但是即使我明確使用了Stage.Development(這是默認的一個),這仍然發生。 有什麼辦法可以避免這種情況?
2)(繼續1)嘗試確保MyServlet首先實例化,即使所有servlet現在都急切實例化,我在創建一個Injector時修改了模塊的順序(和綁定語句),以便爲MyServlet首先出現。然而,我發現,它仍然得到比其他一些綁定(非servlet類的),這是形式的實例化後:
bind(MyInterface.class).to(MyClass.class).asEagerSingleton()
即使那些其他綁定在modules /綁定順序出現較晚。 我仔細研究過它,發現Guice只是簡單地實例化了「bind ... to ... asEagerSingleton()」形式的綁定的單身人士,然後再執行「bind ... asEagerSingleton()」 ,所以我通過修改該行來解決它: bind(MyServlet.class).asEagerSingleton(); (MyServletDummyInterface.class).to(MyServlet.class).asEagerSingleton()
並且實際工作。不過,我寧願避免擁有一個虛擬接口來解決這個問題,所以我想知道是否有人有更好的解決方案。
3)我有兩個Guice模塊 - 一個ServletModule和一個AbstractModule。 的servlet模塊configureServlets()具有以下在它綁定:
serve("aUrl").with(SomeServlet.class);
的AbstractModule的配置()具有以下綁定:
bind(SomeImpl.class).asEagerSingleton();
bind(SomeInterface.class).to(SomeImpl.class).in(Singleton.class);
此外,該SomeServlet類有類型SomeInterface的注入字段,並在課堂上有一個@Singleton註解。
現在,人們會期望創建一個注入器後,SomeImpl類將被實例化,並且同一個實例將被注入到SomeServlet實例中。如前所述,以「serve ... with ...」語句爲界限的servlet似乎也被迫切實例化,但無論哪種方式,只應該有一個SomeImpl對象實例化。然而由於某種原因,我在做這件事時得到了兩個實例化的SomeImpl對象。 要解決它,我在配置兩條線混合()了一下,而不是上面我有下面幾行:
bind(SomeImpl.class).in(Singleton.class)
bind(SomeInterface.class).to(SomeImpl.class).asEagerSingleton();
,然後它工作得很好,我得到的只有一個實例SomeImpl實例化。我真的不明白爲什麼交換機應該重要 - 我可以看到後一種方式是「更好的」,但我希望兩者都能正常工作,所以我只是想知道在這裏是否出現了問題。 ?
很抱歉的長度,
感謝您的幫助!