25

Guiceでは、次の違いは何ですか。

// Inside your AbstractModule subclass:
@Override
public void configure() {
    bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
}

と:

@Override
public void configure() {
    bind(Service.class).to(ServiceImpl.class);
}

@Provides @Singleton
public ServiceImpl providesService() {
    return new ServiceImpl();
}

どちらも同じですか?どちらを使用しますか?前もって感謝します。

4

1 に答える 1

48

それらはほぼ同じです。この@Singleton構文は@Provides、メソッドに注釈を付けたり、クラス自体に注釈を付けたりするのに役立ちます(ただし、スコープの注釈はモジュール内に保持することをお勧めします)。

違いは、キーがシングルトンとマークされていることです。これは、vs @SingletonSingleton.classまたはScopes.SINGLETON、、クラスアノテーション、または暗黙のシングルトン)とは関係がなく、デフォルトの構文で簡単にできることと関係があります。例えば:asEagerSingleton@SingletontoInstance

public class MyModule extends AbstractModule {
  @Override public void configure() {
    bind(A.class).to(AImpl.class).in(Singleton.class);

    bind(B.class).to(BImpl.class);
    bind(BImpl.class).in(Singleton.class);
  }

  @Provides @Singleton C provideC() { return new CImpl(); }

  @Provides @Singleton D provideD(DImpl dImpl) { return dImpl; }

  @Provides E provideE(EImpl eImpl) { return eImpl; }
  @Provides @Singleton EImpl provideEImpl() { return new EImpl(); }
}

上記では、インターフェイスをクラスにバインドし、インターフェイスをクラスにバインドAしましたが、動作は異なります。AImplBBImpl

  • 注入すると、毎回A同じインスタンスが取得されます。AImpl
  • インジェクトは毎回AImpl異なるものを取得しますが、そのすべてがのインスタンスとは異なります。AImplA
  • 注入すると、毎回B同じインスタンスが取得されます。BImpl
  • インジェクトは、インジェクトしたのと同じインスタンスBImplも取得します。BImplB

ご覧のとおり、各キーは異なり、インターフェイスのみがシングルトンにバインドされている場合、Guiceは複数の実装インスタンスを許可します。AインジェクトとインターフェースのみをB使用する場合、動作は同じように見えますが、同じインジェクターからインターフェースと実装の両方を注入すると、動作が異なる場合があります。

同様のロジックが@Providesメソッドにも当てはまります。

  • 注入Cすると、常に同じCImplインスタンスが返されます。
  • 注入可能なパブリックゼロ引数コンストラクターがない場合を除いて、注入は毎回CImpl新しいものを作成します。そうすると、注入は失敗します。CImplCImpl
  • 注入Dすると、常に同じDImplインスタンスが返されます。
  • インジェクトDImplは毎回新しいインスタンスを返し、それぞれがによって返されるインスタンスとは異なりDます。
  • 注入すると、毎回E同じインスタンスが返されます。EImpl
  • インジェクトは、同じインスタンスがインジェクトEImplすることも取得しますE

これにより、ある程度の柔軟性が得られます。Cacheある数の最近取得されたオブジェクトを保持し@User Cache@Product Cache両方を注入可能にするという仮説を想像してみてください。の場合、オブジェクト間(およびベアインジェクション)でbind(Cache.class).in(Singleton.class)1つのキャッシュが共有されますが、その場合、注釈付きキーはシングルトンスコープに保持され、各オブジェクトタイプには独自のキャッシュがあります。Cachebind(Cache.class).annotatedWith(User.class).to(Cache.class).in(Singleton.class)

于 2013-02-09T02:36:54.827 に答える