Guice渴望/懒惰的单例实例化

问题描述 投票:10回答:1

我在理解Guice的单例实例如何工作时遇到了一些麻烦。我已经阅读了可用的文档(在此处-http://code.google.com/p/google-guice/wiki/Scopes),但仍然无法弄清某些内容:

1)我已经将Guice与Tomcat集成在一起,并且已经在ServletModule中设置了一些绑定:

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

((其中MyOtherServlet类在其上方具有@Singleton注释)我的意图是有两个servlet,其中一个被实例化,而另一个则没有。但是,似乎“ serve ... with ...”行自动实例化了servlet对象,即使该类未绑定为一个渴望的单例。我在上面附加的链接提到了Guice在Stage.Development和Stage.Production下运行之间的区别-但是即使我明确使用Stage.Development(无论如何都是默认的),这种情况仍然会发生。有什么办法可以避免这种情况?

2)(继续1),即使现在所有servlet都急切地实例化,也要确保首先实例化MyServlet,我在创建Injector时修改了模块(和绑定语句)的顺序,以便首先显示MyServlet的绑定。 。但是,我发现它仍然比(非servlet类的)其他一些绑定实例化的时间更晚,其形式为:

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

即使这些其他绑定后来在模块/绑定顺序中出现。我研究了一下,发现Guice实例化了渴望的单例,这些单例受“ bind ... to ... asEagerSingleton()”形式的绑定,然后才执行“ bind ... asEagerSingleton()”,所以我通过修改以下行解决了它:bind(MyServlet.class).asEagerSingleton();变成:bind(MyServletDummyInterface.class).to(MyServlet.class).asEagerSingleton()

并且实际上有效。尽管如此,我还是希望避免使用虚拟接口来解决此问题,所以我想知道是否有人对此有更好的解决方案。

3)我有两个Guice模块-一个ServletModule和一个AbstractModule。ServletModule configureServlets()具有以下绑定:

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

AbstractModule的configure()具有以下绑定:

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

此外,SomeServlet类具有注入接口类型SomeInterface,并且在类顶部具有@Singleton批注。

现在,人们希望在创建注入器后,将实例化SomeImpl类,并将同一实例注入到SomeServlet实例中。如前所述,以“ serve ... with ...”语句为界的servlet似乎也被实例化了,但是无论哪种方式,实例化仍然应该只有一个SomeImpl对象。但是由于某种原因,我在执行此操作时实例化了两个SomeImpl对象。为了解决这个问题,我在configure()中混合了两行,而不是上面的行:

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

然后运行正常,我只实例化了SomeImpl的一个实例。我真的不知道为什么切换应该很重要-我可以看到后一种方式“更好”,但是我希望两者都能正常工作,所以我只是想知道我在这里是否出错了。 ?

对不起,长度,感谢您的帮助!

我在理解Guice的单例实例如何工作时遇到了一些麻烦。我已经阅读了可用的文档(在这里-http://code.google.com/p/google-guice/wiki/Scopes),但是我仍然无法...

java singleton guice eager
1个回答
9
投票

1]无法避免这种情况,因为Guice在初始化其自己的过滤器管道时调用所有servlet的init()方法,从而构造了所有servlet。如果您确实需要这种懒惰的初始化逻辑,则应将其放入servlet本身(或使用解耦的帮助器类,或者...有多种方法,具体取决于您的用例)。

2)通常来说,Guice 声明绑定

© www.soinside.com 2019 - 2024. All rights reserved.