Locked History Actions

Diff for "guice/Manual/UserGuide/Injections"

Differences between revisions 2 and 3
Deletions are marked like this. Additions are marked like this.
Line 28: Line 28:
しかし、アノテーションすることが推奨される。それが依存性注入されることドキュメント化するからである。 しかし、この場合にもアノテーションすることが推奨される。依存性注入されることドキュメントになるからである。
Line 36: Line 36:
Guice can inject methods that have the @Inject annotation. Dependencies take the form of parameters, which the injector resolves before invoking the method. Injected methods may have any number of parameters, and the method name does not impact injection. Guiceは@Injectアノテーション付のメソッドを使ってインジェクションする。
依存はパラメータで表され、インジェクタはそのメソッドの起動に先立って依存を解決する。
インジェクトされるメソッドは、いくつのパラメータを持ってもよいし、メソッド名はどのようなものでもよい。
Line 50: Line 52:
== Field Injection == == フィールドインジェクション ==
Line 52: Line 54:
Guice injects fields with the @Inject annotation. This is the most concise injection, but the least testable. Guiceは@Injectアノテーション付のフィールドにインジェクトする。
これが最も簡単なインジェクト方法であるが、しかし最もテストしにくい。
Line 63: Line 66:
Avoid using field injection with final fields, which has weak semantics.
== Optional Injections ==
finalフィールドにインジェクションするのは避けるべきである。それはweak semanticsである。
Line 66: Line 68:
Occasionally it's convenient to use a dependency when it exists and to fall back to a default when it doesn't. Method and field injections may be optional, which causes Guice to silently ignore them when the dependencies aren't available. To use optional injection, apply the @Inject(optional=true) annotation: == オプショナルインジェクション ==

依存が存在するときにだけインジェクションを行い、存在しない場合はデフォルトにフォールバックするのが便利なこともある。
メソッドとフィールドのインジェクションはオプションにすることもできる。
その場合、もし依存が存在しなければGuiceは何のエラーも発生せずに蒸しする。
オプショナルインジェクションを用いるには、@Inject(optional=true)アノテーションを使う。
Line 78: Line 86:
Mixing optional injection and just-in-time bindings may yield surprising results. For example, the following field is always injected even when Date is not explicitly bound. This is because Date has a public no-arguments constructor that is eligible for just-in-time bindings. オプショナルインジェクションとその場バインディングを混在させると、意外な結果が発生する場合がある。
例えば、次のフィールドは、Dateの明示的バインディングがなくても常にインジェクトされる。
なぜなら、Dateはその場バインディングで利用可能なpublicな引数無しのコンストラクタを持つからである。
Line 82: Line 92:
== requestInjection ==
Line 84: Line 93:
Method and field injection can be used to initialize an existing instance. You can use the Injector.injectMembers API: == リクエストインジェクション ==

メソッド及びフィールドインジェクションは既存のインスタンスを初期化するのに用いることができる。
これはInjector.injectMembersによって行われる。
Line 93: Line 105:
== Static Injections == == スタティックインジェクション ==
Line 117: Line 130:
== Automatic Injection ==
Line 119: Line 131:
Guice automatically injects all of the following: == 自動インジェクション ==
Line 121: Line 133:
 * instances passed to toInstance() in a bind statement
 * provider instances passed to toProvider() in a bind statement
Guice以下のすべてを自動的にインジェクトする。

 * bind()ステートメント中のtoInstance()に指定されたインスタンス
 * bind()ステートメント中のtoProvider()に指定されたプロバイダインスタンス

インジェクション

依存性注入パターンはふるまいと依存性解決を分離する。 ファクトリによって、依存を直接的にルックアップするより、依存を引き渡すことが推奨される。 依存をオブジェクトにセットすることはインジェクションと呼ぶ

コンストラクタインジェクション

コンストラクタインジェクションはインスタンス作成とインジェクションを組み合わせたものである。 コンストラクタに@Injectアノテーションを用いることにより使う。 このコンストラクタはパラメータとして依存性を受け取る。 大抵のコンストラクタでは、これらのパラメータをfinalフィールドに代入する。

public class RealBillingService implements BillingService {
  private final CreditCardProcessor processorProvider;
  private final TransactionLog transactionLogProvider;

  @Inject
  public RealBillingService(CreditCardProcessor processorProvider,
      TransactionLog transactionLogProvider) {
    this.processorProvider = processorProvider;
    this.transactionLogProvider = transactionLogProvider;
  }

もし、@Injectアノテーション付のコンストラクタが無い場合、(もしあれば)Guiceはpublicな引数無しのコンストラクタを使用する。 しかし、この場合にもアノテーションすることが推奨される。依存性注入されることのドキュメントになるからである。

コンストラクタインジェクションはユニットテストに最適である。 もし、そのクラスのすべての依存が一つのコンストラクタによって与えることができるならば、依存を設定し忘れることはない。 新たな依存を追加すると、呼び出しコードが不正になるため、そのコンパイルエラーを直しさえすれば、すべてがきちんとワイアリングされていることを確信することができる。

メソッドインジェクション

Guiceは@Injectアノテーション付のメソッドを使ってインジェクションする。 依存はパラメータで表され、インジェクタはそのメソッドの起動に先立って依存を解決する。 インジェクトされるメソッドは、いくつのパラメータを持ってもよいし、メソッド名はどのようなものでもよい。

public class PayPalCreditCardProcessor implements CreditCardProcessor {
  
  private static final String DEFAULT_API_KEY = "development-use-only";
  
  private String apiKey = DEFAULT_API_KEY;

  @Inject
  public void setApiKey(@Named("PayPal API key") String apiKey) {
    this.apiKey = apiKey;
  }

フィールドインジェクション

Guiceは@Injectアノテーション付のフィールドにインジェクトする。 これが最も簡単なインジェクト方法であるが、しかし最もテストしにくい。

public class DatabaseTransactionLogProvider implements Provider<TransactionLog> {
  @Inject Connection connection;

  public TransactionLog get() {
    return new DatabaseTransactionLog(connection);
  }
}

finalフィールドにインジェクションするのは避けるべきである。それはweak semanticsである。

オプショナルインジェクション

依存が存在するときにだけインジェクションを行い、存在しない場合はデフォルトにフォールバックするのが便利なこともある。 メソッドとフィールドのインジェクションはオプションにすることもできる。 その場合、もし依存が存在しなければGuiceは何のエラーも発生せずに蒸しする。 オプショナルインジェクションを用いるには、@Inject(optional=true)アノテーションを使う。

public class PayPalCreditCardProcessor implements CreditCardProcessor {
  private static final String SANDBOX_API_KEY = "development-use-only";

  private String apiKey = SANDBOX_API_KEY;

  @Inject(optional=true)
  public void setApiKey(@Named("PayPal API key") String apiKey) {
    this.apiKey = apiKey;
  }

オプショナルインジェクションとその場バインディングを混在させると、意外な結果が発生する場合がある。 例えば、次のフィールドは、Dateの明示的バインディングがなくても常にインジェクトされる。 なぜなら、Dateはその場バインディングで利用可能なpublicな引数無しのコンストラクタを持つからである。

  @Inject(optional=true) Date launchDate;

リクエストインジェクション

メソッド及びフィールドインジェクションは既存のインスタンスを初期化するのに用いることができる。 これはInjector.injectMembersによって行われる。

  public static void main(String[] args) {
    Injector injector = Guice.createInjector(...);
    
    CreditCardProcessor creditCardProcessor = new PayPalCreditCardProcessor();
    injector.injectMembers(creditCardProcessor);

スタティックインジェクション

When migrating an application from static factories to Guice, it is possible to change incrementally. Static injection is a helpful crutch here. It makes it possible for objects to partially participate in dependency injection, by gaining access to injected types without being injected themselves. Use requestStaticInjection() in a module to specify classes to be injected at injector-creation time:

  @Override public void configure() {
    requestStaticInjection(ProcessorFactory.class);
    ...
  }

Guice will inject class's static members that have the @Injected annotation:

class ProcessorFactory {
  @Inject static Provider<Processor> processorProvider;

  /**
   * @deprecated prefer to inject your processor instead.
   */
  @Deprecated
  public static Processor getInstance() {
    return processorProvider.get();
  }
}

Static members will not be injected at instance-injection time. This API is not recommended for general use because it suffers many of the same problems as static factories: it's clumsy to test, it makes dependencies opaque, and it relies on global state.

自動インジェクション

Guice以下のすべてを自動的にインジェクトする。

  • bind()ステートメント中のtoInstance()に指定されたインスタンス
  • bind()ステートメント中のtoProvider()に指定されたプロバイダインスタンス

The objects will be injected while the injector itself is being created. If they're needed to satisfy other startup injections, Guice will inject them before they're used.