1

シングルトンをプロバイダーのパラメーターにバインドする方法を知りたいです。

すなわち:

@Singleton
public class RunButtonController{
    @Inject
    public RunButtonController(EventBus eventbus){ ... }

    public JComponent getView(){
        return view;
    }
    ...
}

public class UncaughtExceptionController{
    @Inject
    public UncaughtExceptionController(
        EventBus eventBus, ..., 
        @Named(DefaultExceptionViewKey) JComponent defaultView)
    { ... }
    ...
}

public class GUIController{
    //another consumer of RunButtonController, arguably the "main" consumer. 
    @inject
    public GUIController(RunButtonController runButtonController,
                         UncaughtExceptionController uncaughtExceptionController, ...)
    { ... }
    ...
}

public class Bootstrapper{
    public static void main(String[] args){

        Injector injector = Guice.createInjector(new OptipModule());

        GUIController controller = injector.getInstance(GUIController.class);
    }

    private static class OptipModule extends AbstractModule{

        @Override
        protected void configure() {
            bind(EventBus.class).toInstance(new EventBus("OPTIPGlobalEventBus"));
            bind(JFrame.class).to(GUIView.class);
        }

        @Provides @Named(DefaultExceptionViewKey)
        public JComponent getFrom(RunButtonController runButtonController){
            return runButtonController.getView();
        }
    }
}

コンストラクターにブレークポイントを設定すると、RunButtonController一貫して 2 回インスタンス化されることがわかります。一度だけインスタンス化して defaultExceptionViewProvider == runButtonControllertrue.

私は Castle Windsor をかなり広範囲に使用してきましたが、それが私が使用した唯一の IOC コンテナーであるため、私は新しいことに慣れていません。私は訪問者の行動の名残をいたるところで見ています.guiceのドキュメントは、クラスの定義された動作(つまり、インスタンスを1回使用し、このインスタンスを使用し、このファクトリを使用するなど)がそれ以上持続しないことをかなり明確にしています.構成されたモジュール。を使用すると、guice が子モジュールを作成することが書かれているのを見たと言いたい@Providesので、おそらく私がする必要があるのは、この子 @Provides で生成されたモジュールに「ねえ、このクラスはシングルトンです」と伝えることです。私はそれを解決する過程にあるので、ここにあります! あなた自身のものを使わないでください!

私はこのフレームワークについて間違った方向に進んでいると思います。私は注釈を壊してデバッグを行ってきましたが、おそらく私が本当にする必要があるのは、良いチュートリアルを読むのに数時間を費やすことです.残念ながら、私はそれを見つけることができません. JavaDoc には例があり、Web ページにはそれらが公開されていますが、コンテキストがほとんどないため、@Assisted に関する記事を3 回読んでも、まだ理解できません (おそらく、それを使用する必要があるのでしょうか?)。特に詳細なブロガーと彼のページのガイドエントリの方向を指し示している誰かのために。

これらの線に沿って、非常に余談ですが、この「デフォルトの通知領域は、この他の人のビューです」を IOC コンテナにプッシュしようとすることの影響は何なのか疑問に思っています。それはおそらくドメインロジックですか?UnhandledExceptionControllerビューが によって提供されたことを に知られたくありませRunButtonControllerん。同様に、RunButtonControllerそのビューがビュー ツリーにスタンプされる以外の目的で使用されていることを に知られたくありません。

読んでくれてありがとう!

4

1 に答える 1

2

投稿されたように、コードは機能するはずです。とはいえ、シングルトンが共存する可能性があるいくつかの注意事項があります。各コンストラクター呼び出しのスタック トレースを再確認します。

  • 当然のことかもしれませんが、Guice の制御外で任意の数のインスタンスを作成することができ、Guice はそれらのインスタンスが存在することを知る方法がありません。コード内でRunButtonControllerコンストラクターを手動で呼び出すものがないことを再確認してください。

  • シングルトンの動作は、特定のインジェクター内で強制されます。アプリケーションに 2 つ以上のインジェクターがある場合、それぞれが の独自のインスタンスを作成できますRunButtonController。ただし、親インジェクターで宣言されたシングルトンは、すべての子インジェクターに表示されます。

  • シングルトンはキーで機能します。注釈を削除して@Singletonこれを追加する場合:

    bind(RunButtonController.class)
        .annotatedWith(Names.named("Foo"))
        .asEagerSingleton()
    

    次に、注入するRunButtonControllerと毎回新しいインスタンスが@Named("Foo") RunButtonController取得されますが、注入すると、毎回同じものを返す個別のシングルトン インスタンスが取得されます。@Singletonはクラス自体にあるため、おそらくあなたには当てはまりませんが、以前に他の人を噛んだことがあります。

  • 継承に依存していないようですが、シングルトン アノテーションはスーパークラスからサブクラスに継承されないことを覚えておいてください。

補足:@Providesメソッドは子インジェクター経由では機能しませんが、プライベート モジュールは機能します (ドキュメントでは「親インジェクター」と言及されています)。内部的には、別の内部モジュールがこれらのプロバイダー メソッドの呼び出しを担当しているのは事実ですが、それは実際には問題ではありません。シングルトンはモジュール間で共有されます。

@Named(DefaultExceptionViewKey) JComponentビューの共有に関する余談について:の代わりに注入することで、すでにかなりうまくやっていますRunButtonControllerが、さらに実装に依存したくない場合は、ExceptionHandlerComponentインターフェイスを作成し、それに対してコードを作成できます。

于 2013-08-14T21:46:20.410 に答える