3

私は、任意の Bean クラスに API からのクラスが注入されるフレームワークを作成しようとしています。これらのクラスは、定義された注釈に基づいてコールバックをトリガーするだけでなく、それらの両方のクラスとやり取りすることもできます。Bean の例を次に示します。

@Experiment
static class TestExperiment {
    private final HITWorker worker;
    private final ExperimentLog log;
    private final ExperimentController controller;

    @Inject
    public TestExperiment(
        HITWorker worker,
        ExperimentLog expLog,
        ExperimentController controller
        ) {         
        this.worker = worker;
        this.expLog = expLog;
        this.controller = controller;
    }

    @SomeCallback
    void callMeBack() {
        ... do something

        log.print("I did something");
    }

}

Guice を使用してこれらの Bean を注入し、注入されたクラス間の相互依存関係を処理しようとしています。ただし、次の 2 つの問題があります。

  • ( ) で渡すクラスの 1 つは、HITWorker既にインスタンス化されています。Providerコードを大幅に複雑にすることなく、これを a に移動する方法がわかりませんでした。これも永続的ですが、Guice で定義されたセッションまたはリクエスト スコープに対してではありません。そのため、今のところ自分で管理しています。(おそらく、他の問題が解決されれば、これをプロバイダーに入れることができます。)
  • さらに重要なことは、他の注入されたクラスへの参照が必要であるため、それらに対して適切なことを行うことができるということです。Guice がそれらを注入すると、Bean クラスが任意であるため、それらにアクセスできません。

これは、私が基本的に行う必要があることの本当に悪いコードです。これは、すべての適切な依存性注入の概念に違反していると確信しています。hitw渡す必要があるのは 1 つのインスタンスのみですが、他の依存オブジェクトへの参照が必要なため、他の依存オブジェクトも作成していることに注意してください。このコードでは、依存関係の解決ではなく、基本的にリフレクション コードにのみ Guice を使用しています。

private void initExperiment(final HITWorkerImpl hitw, final String expId) {         
    final ExperimentLogImpl log = new ExperimentLogImpl();
    final ExperimentControllerImpl cont = new ExperimentControllerImpl(log, expManager);

    // Create an experiment instance with specific binding to this HITWorker
    Injector child = injector.createChildInjector(new AbstractModule() {
        @Override
        protected void configure() {
            bind(HITWorker.class).toInstance(hitw);
            bind(ExperimentLog.class).toInstance(log);
            bind(ExperimentController.class).toInstance(cont);
        }           
    });     

    Object experimentBean = child.getInstance(expClass);        

    expManager.processExperiment(expId, experimentBean);

    // Initialize controller, which also initializes the log
    cont.initialize(expId);

    expManager.triggerStart(expId);

    tracker.newExperimentStarted(expId, hitw, cont.getStartTime());
}

私はめちゃくちゃで、自分のインジェクション コードを書く必要がありますか、それともこれを適切に行う方法はありますか? また、これらの Bean クラスのコンストラクター インジェクションについても忘れてはいけません。自分で行うのではなく、Guice に Bean を注入するように依頼している場合、依存関係を取得する方法はありますか?

文脈のために、私はGuiceのドキュメントを読んで、これについて数日間例を見てきましたが、役に立ちませんでした。私は完全なプログラミングバカではないと思いますが、これを適切に行う方法がわかりません!

4

1 に答える 1

1

あなたの「実験」は、定義されたライフサイクルと、実験が自由に引き込むことができるいくつかの関連するものを持っているという意味で、「リクエスト」のようなもののようです。

したがって、カスタムスコープに関するドキュメントで説明されているように、すべてをカスタムスコープにラップする必要があると思います。これはいくつかの点であなたのケースと一致します:

  • スコープにいくつかのオブジェクトを「シード」できます(あなたのHITWorker
  • ライフサイクル: 実験をセットアップする前に「範囲に入る」ことを行い、作業が完了したら「範囲を終了する」ことを行います。
  • ExperimentLogやのような「共有」のものへExperimentControllerのアクセス: それらをスコープにバインドします。次に、フレームワークと実験インスタンスの両方がそれらを単純@Inject化し、同じインスタンスを取得できます。
于 2012-12-04T19:37:15.480 に答える