Locked History Actions

Diff for "guice/Manual/UserGuide/Scopes"

Differences between revisions 1 and 2
Deletions are marked like this. Additions are marked like this.
Line 66: Line 66:
Guice has special syntax to define singletons that can be constructed eagerly: Guiceは早期に生成されるシングルトンのための特別なシンタックスを持つ。
Line 70: Line 70:
Eager singletons reveal initialization problems sooner, and ensure end-users get a consistent, snappy experience. Lazy singletons enable a faster edit-compile-run development cycle. Use the Stage enum to specify which strategy should be used. Eagerシングルトンでは初期化エラーを早期に発見することができるし、エンドユーザは一貫性のあるきびきびした動きを得ることができる。
(これに対して)Lazyシングルトンでは、素早いedit-compile-run開発サイクルを提供する。
Stage enumにより、どちらのモードを選択するか決めることができる。
Line 72: Line 74:
 || PRODUCTION|  DEVELOPMENT|
 |.asEagerSingleton()|  eager|  eager|
 |.in(Singleton.class)|  eager|  lazy|
 |.in(Scopes.SINGLETON)|  eager|  lazy|
 |@Singleton|  eager*|  lazy|
|| || PRODUCTION||DEVELOPMENT||
||.asEagerSingleton()||eager||eager||
||.in(Singleton.class)||eager||lazy||
||.in(Scopes.SINGLETON)||eager||lazy||
||@Singleton|eager*||lazy||
Line 78: Line 80:
* Guice will only eagerly build singletons for the types it knows about. These are the types mentioned in your modules, plus the transitive dependencies of those types.
Choosing a scope
※Guiceはその知識のあるシングルトンについてのみ早期生成を行う。これらはモジュール内で指定されたものと、そこから依存されているものである。(訳注:@Singletonアノテーションはだめ?)


== スコープの選択 ==
Line 89: Line 93:
Scopes and Concurrency == スコープと平行性 ==

スコープ

デフォルトでは、Guiceは常に新しいインスタンスを作成して返す。 このふるいまいはスコープによって変更可能である。 スコープによってインスタンスを再利用することができる。 つまり、そのライフタイムをアプリケーション(@Singleton)、セッション(@SessionScoped)、リクエスト(@RequestScoped)と区別することができる。

Guiceはウェブアプリ用のスコープを定義するためのサーブレット拡張を提供している。 それ以外のアプリケーションでは、カスタムスコープを作成することができる。

スコープの適用

Guiceはスコープを識別するためにアノテーションを使う。 実装クラスにスコープアノテーションを適用することにより、そのタイプのスコープを指定することができる。 機能的にもそうだが、ドキュメント用ととしてもこれらのアノテーションは役に立つ。 例えば、@Singletonはこのクラスがスレッドセーフであるべきことを示す(訳注:そうとは限らないと思うけど)。

@Singleton
public class InMemoryTransactionLog implements TransactionLog {
  /* ここにあるものはすべてスレッドセーフであること */
}

スコープはbindにおいても指定することができる。

  bind(TransactionLog.class).to(InMemoryTransactionLog.class).in(Singleton.class);

また、@Providesメソッドに指定することもできる。

  @Provides @Singleton
  TransactionLog provideTransactionLog() {
    ...
  }

タイプ(のアノテーション)とbind()でスコープが異なる場合は、bind()の方が優先される。 アノテーションされたスコープをキャンセルしたい場合には、bind()時にScopes.NO_SCOPEを使うことができる。

リンクバインディングにおいては、スコープはバインディングソースの方に適用される。バインディングターゲットではない。 例えば、Bar,Grillインターフェースを実装するApplebeesというクラスがあるとする。 以下の二つのバインディングは二つのインスタンスを許す、一つはBar向けのもの、もう一つはGrill向けのものである。

  bind(Bar.class).to(Applebees.class).in(Singleton.class);
  bind(Grill.class).to(Applebees.class).in(Singleton.class);

なぜかというと、スコープはバインドされるタイプ(Bar, Grill)に適用されるからであり、それらのタイプを満足するバインディング(Applebees)ではないからである。 もしただ一つのインスタンスだけを作成したいのであれば、そのクラスに対して@Singletonアノテーションを使うか、あるいは別のバインディングを使う必要がある。

  bind(Applebees.class).in(Singleton.class);

このバインディングを使うと、他の二つのバインディングの.in(Singleton.class)句は不要になる。

in()句にはRequestScoped.classのようなアノテーションを入れることもできるし、ServletScopes.REQUESTといったインスタンスを入れることもできる。

  bind(UserPreferences.class)
      .toProvider(UserPreferencesProvider.class)
      .in(ServletScopes.REQUEST);

アノテーションを使った方が望ましい。そのモジュールは別のタイプのアプリケーションでも再利用可能だからだ。 例えば、@RequestScopedオブジェクトであれば、ウェブアプリにおけるHTTPリクエストのスコープとして使うこともできるし、 APIサーバのRPCリクエストとして使うことができるからだ。

Eagerシングルトン

Guiceは早期に生成されるシングルトンのための特別なシンタックスを持つ。

  bind(TransactionLog.class).to(InMemoryTransactionLog.class).asEagerSingleton();

Eagerシングルトンでは初期化エラーを早期に発見することができるし、エンドユーザは一貫性のあるきびきびした動きを得ることができる。 (これに対して)Lazyシングルトンでは、素早いedit-compile-run開発サイクルを提供する。 Stage enumにより、どちらのモードを選択するか決めることができる。

PRODUCTION

DEVELOPMENT

.asEagerSingleton()

eager

eager

.in(Singleton.class)

eager

lazy

.in(Scopes.SINGLETON)

eager

lazy

@Singleton|eager*

lazy

※Guiceはその知識のあるシングルトンについてのみ早期生成を行う。これらはモジュール内で指定されたものと、そこから依存されているものである。(訳注:@Singletonアノテーションはだめ?)

スコープの選択

If the object is stateful, the scoping should be obvious. Per-application is @Singleton, per-request is @RequestScoped, etc. If the object is stateless and inexpensive to create, scoping is unnecessary. Leave the binding unscoped and Guice will create new instances as they're required.

Singletons are popular in Java applications but they don't provide much value, especially when dependency injection is involved. Although singletons save object creation (and later garbage collection), getting a handle to the single instance requires synchronization. Singletons are most useful for:

  • stateful objects, such as configuration or counters
  • objects that are expensive to construct or lookup
  • objects that tie up resources, such as a database connection pool.

スコープと平行性

Classes annotated @Singleton and @SessionScoped must be threadsafe. Everything that's injected into these classes must also be threadsafe. Minimize mutability to limit the amount of state that requires concurrency protection.

@RequestScoped objects do not need to be threadsafe. It is usually an error for a @Singleton or @SessionScoped object to depend on an @RequestScoped one. Should you require an object in a narrower scope, inject a Provider of that object.