3

次のプロバイダーがあります。

  public class GuiceResourceProvider implements Provider<WebResource> {

    @Inject
    private Configuration configuration;
    @Inject
    private Environment environment;

    private String name;

    @Inject
    public GuiceResourceProvider(@Assisted("name") String name) {
        this.name = name;
    }

    @Override
    public WebResource get() {
        if (name == "default") {
            String connectionsDSResourceUrl = "http://localhost:" + this.configuration.getHttpConfiguration().getPort();
            Client connectionsDSHttpClient = new JerseyClientBuilder().using(this.configuration.getHttpClientConfiguration()).using(this.environment).build();
            connectionsDSHttpClient.addFilter(new RequestIdClientFilter());
            return connectionsDSHttpClient.resource(connectionsDSResourceUrl);
        } else if(name == "other"){
            return ......
        }
    }
}

このプロバイダーの 2 つのインスタンスを作成する必要があります。1 つは "default" という注釈が付けられた WebResource インジェクションをバインドし、もう 1 つは "other" という注釈が付けられた WebResource インジェクションをバインドします。

次のように、Guice に Provider インスタンスを作成させます。

    bind(WebResource.class).annotatedWith(Names.named("default")).toProvider(GuiceResourceProvider.class).in(Scopes.SINGLETON);
bind(WebResource.class).annotatedWith(Names.named("other")).toProvider(GuiceResourceProvider.class).in(Scopes.SINGLETON);

注入されたパラメーターは問題ありませんが、カスタム パラメーターを提供することはできません。インスタンスを手動でインスタンス化してカスタム パラメータを指定しようとすると、もちろん注入されたものに問題があります。Assisted 表記に従う場合、問題は、プロバイダーのファクトリーをモジュールに注入する必要があることです。もちろん、これは完全にオフです!

誰でも助けることができますか?

4

2 に答える 2

4

興味があるかもしれないすべての人のために、私は答えを見つけました。注入されたパラメーターとカスタム パラメーターの両方をプロバイダーに渡したい場合は、注入されたパラメーターをコンストラクターからフィールドに移動し、コンストラクターを使用して独自のパラメーターを渡します。バインドするときは、最初にプロバイダーのインスタンスを作成してパラメーターをコンストラクターに渡します。次に、このインスタンスで requestInjection を呼び出してインジェクション グラフに追加し、次のようにクラスをプロバイダー インスタンスにバインドします。

GuiceResourceProvider guiceResourceProvider = new GuiceResourceProvider("default");
requestInjection(guiceResourceProvider);

bind(WebResource.class).annotatedWith(Names.named("default")).toProvider(guiceResourceProvider).in(Scopes.SINGLETON);

これはプロバイダーです:

public class GuiceResourceProvider implements Provider<WebResource> {

@Inject
private Configuration configuration;
@Inject
private Environment environment;

private String name;

@Inject
public GuiceResourceProvider(String name) {
    this.name = name;
}

@Override
public WebResource get() {
    if (name == "default") {
        String connectionsDSResourceUrl = "http://localhost:" + this.configuration.getHttpConfiguration().getPort();
        Client connectionsDSHttpClient = new JerseyClientBuilder().using(this.configuration.getHttpClientConfiguration()).using(this.environment).build();
        connectionsDSHttpClient.addFilter(new RequestIdClientFilter());
        return connectionsDSHttpClient.resource(connectionsDSResourceUrl);
    } else if(name == "other"){
        return ......
    }
}

}

于 2013-02-26T06:57:03.473 に答える
1

ここにはいくつかの間違いがあります:

  • 文字列を==と比較するのではなく、 と比較してくださいequals==は参照によって比較されますが、この 2 つは等しい文字列の異なるインスタンスへの参照である可能性があります。
  • Provider は、引数のないファクトリです。ファクトリがある場合、プロバイダーは必要ありません。
  • アシスト インジェクションは、 のようなバインディング アノテーションとは異なるシステムです@Named。バインド アノテーションは、プロバイダーを検索するためのマップ キーの半分にすぎません (クラスまたは TypeLiteral は残りの半分です)。アシスト注入を使用すると、注入時に 1 つまたは複数のパラメーターを取得し、これを行うインターフェイスを自動的に接続できます。アシスト注入パラメーターは@Assisted("foo")、1 つのファクトリー メソッドで同じパラメーター タイプを複数受け入れる場合にのみ、アノテーションを受け取ります。それ以外の場合は、Guice がそれを把握できます。
  • 注入している依存関係内からバインディング アノテーションのパラメーター値を読み取る良い方法はありませんが、異なるパラメーター値を持つバインディング アノテーションは互いに等しくないため、それぞれを個別にバインドできます。

あなたのロジックは@Providesメソッドで最もよく見えると思います:

public class WebResourceModule extends AbstractModule {

  @Override public void configure() { }

  @Provides @Named("default") @Singleton WebResource makeDefaultResource(
      Configuration configuration, Environment environment) {
    String connectionsDSResourceUrl = "http://localhost:" + this.configuration.getHttpConfiguration().getPort();
    Client connectionsDSHttpClient = new JerseyClientBuilder().using(this.configuration.getHttpClientConfiguration()).using(this.environment).build();
    connectionsDSHttpClient.addFilter(new RequestIdClientFilter());
    return connectionsDSHttpClient.resource(connectionsDSResourceUrl);
  }

  @Provides @Named("other") @Singleton WebResource makeOtherResource(
      YourDependencies here) {
    return somethingElse();
  }
}

ただし、カスタム ファクトリ ロジックを使用して任意の文字列を取得する場合は、 を実装しない単一メソッドの注入可能なクラスProviderを作成し、それを使用して任意の文字列を作成して返しWebResourceます。

于 2013-02-25T18:59:47.553 に答える