Guice のシングルトンのインスタンス化がどのように機能するかを理解するのに苦労しています。利用可能なドキュメント (ここ - http://code.google.com/p/google-guice/wiki/Scopes ) を読みましたが、まだいくつかのことがわかりません:
Guice を Tomcat に統合し、ServletModule にいくつかのバインディングをセットアップしました。
bind(MyServlet.class).asEagerSingleton(); serve("myUrl").with(MyServlet.class); serve("myOtherUrl").with(MyOtherServlet.class);
(ここで MyOtherServlet クラスには @Singleton アノテーションが上にあります) ここでの私の意図は、2 つのサーブレットを用意することでした。一方は積極的にインスタンス化され、もう一方はそうではありません。ただし、そのクラスが熱心なシングルトンとしてバインドされていない場合でも、「serve ... with ...」行はサーブレットオブジェクトを自動的にインスタンス化するようです。上に添付したリンクは、Stage.Development と Stage.Production で実行されている Guice の違いについて言及していますが、Stage.Development を明示的に使用した場合でも、これは依然として発生しました (これはとにかくデフォルトです)。これを回避する方法はありますか?
(1 に続く) すべてのサーブレットが熱心にインスタンス化されるようになったとしても、MyServlet が最初にインスタンス化されるようにするために、インジェクターを作成するときにモジュール (およびバインディング ステートメント) の順序を変更して、MyServlet のバインディングが最初に表示されるようにしました。ただし、次の形式の他のバインディング (サーブレット以外のクラス) よりも後でインスタンス化されることがわかりました。
bind(MyInterface.class).to(MyClass.class).asEagerSingleton()
これらの他のバインディングは、モジュール/バインディングの順序で後で表示されますが。私が調べたところ、Guice は「bind... asEagerSingleton()」のフォームを実行する前に、「bind... to... asEagerSingleton()」の形式でバインドされた熱心なシングルトンを単純にインスタンス化することがわかりました。そのため、次の行を変更して解決しました。
bind(MyServlet.class).asEagerSingleton();
の中へ:
bind(MyServletDummyInterface.class).to(MyServlet.class).asEagerSingleton()
そしてそれは実際に機能しました。それでも、これを解決するためだけにダミーのインターフェースを使用することは避けたいので、誰かがこれに対するより良い解決策を持っているかどうか疑問に思っていました..?
2 つの Guice モジュールがあります。1 つは ServletModule で、もう 1 つは 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..." ステートメントでバインドされたサーブレットも積極的にインスタンス化されるように見えますが、いずれにしてもインスタンス化される SomeImpl オブジェクトは 1 つだけです。しかし、何らかの理由で、これを実行すると 2 つの SomeImpl オブジェクトがインスタンス化されました。これを回避するために、configure() の 2 行を少し混ぜて、上記の代わりに次の行を追加しました。
bind(SomeImpl.class).in(Singleton.class)
bind(SomeInterface.class).to(SomeImpl.class).asEagerSingleton();
その後、正常に動作し、インスタンス化された SomeImpl のインスタンスが 1 つだけになりました。なぜスイッチが重要なのかはよくわかりません.後者の方法が「より良い」方法であることはわかりますが、両方が正しく機能することを期待しているので、ここで何か問題があるのではないかと思っています.. .