0

Guiceは、いわゆるバインディングアノテーションの2つのバリエーションを提供します。これらは、実際にはクラスレベルとインスタンスレベルのアノテーションに分類されるようです。

「クラスレベル」:

bind(Service.class).annotatedWith(Red.class).to(RedServiceImpl.class);

@Red
public class SomeService implements Service { ... }

Service redSvc = injector.getInstance(SomeService.class);

「インスタンスレベル」:

bind(Service.class).annotatedWith(Names.named("Blue").to(BlueServiceImpl.class);
@Blue blueSvc = injector.getInstance(Service.class);

ある方法が他の方法よりも優先されるのはいつですか?クラスレベルのアノテーションは、インスタンスレベルよりも絶対的/柔軟性がないようです。どちらの方法の長所/短所/警告/落とし穴?

4

2 に答える 2

1

あなたの質問を理解できるかわかりません。バインディングアノテーションの使用は不規則です。通常、ローカル変数やクラスに注釈を付けるのではなく、フィールドとパラメーターに注釈を付けます。

最初のコード例で、インジェクターがSomeServiceを返しますが、アノテーションやバインディングが原因ではなく、SomeServiceが具体的な実装であるためです。代わりにこれを求めましたか:

Service redSvc = injector.getInstance(Service.class);

エラーが発生します:

1) No implementation for com.example.Service was bound.
  while locating com.example.Service

2番目の例も正しくありません。を使用Namesしてバインディングを定義する場合は、を使用@Namedしてそのバインディングにアクセスする必要があります。を使用@Blueすると、コンパイラエラーが発生します。正しい使用法はです@Named(value="Blue")

バインディングアノテーションの一般的なベストプラクティスは次のとおりです。

@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface MyAnno

その場合、これらは両方ともコンパイルエラーになります。

@Red // not allowed
public class SomeService implements Service { ... }

@Blue // not allowed
blueSvc = injector.getInstance(Service.class);
于 2012-04-15T04:08:57.303 に答える
0

唯一の本当の違いは、1つのケースではアノテーション全体をバインドし、他のケースでは特定の引数を使用してアノテーションにバインドすることです。すべてのアノテーションが引数を取るわけではありません。その場合、アノテーションクラスとのバインドは完全に正常です。

于 2012-04-13T14:37:24.510 に答える