Guice2.0 beta 紹介記事の翻訳(5)

原文:IBM Developer : Sorry, that page no longer exists
訳1:Guice2.0 beta 紹介記事の翻訳(1) - 山本大の日記
訳2:Guice2.0 beta 紹介記事の翻訳(2) - 山本大の日記
訳3:Guice2.0 beta 紹介記事の翻訳(3) - 山本大の日記
訳4:Guice2.0 beta 紹介記事の翻訳(4) - 山本大の日記

プロバイダーメソッド(Provider methods)

Other uses for provider methods
If you're nervous about the annotations that come with the Guice territory, or if you can't use them (you're creating a third-party class, for instance), provider methods solve your problem elegantly. Because your provider method lives in your module, you can annotate it without worrying that the rest of your source will see the annotations. For example, Listing 16 contains a provider method for BadgerBoy (a third-party hero):


リスト16. プロバイダメソッドを使えば、ソースにアノテートせずアノテーションが使える。(A provider method allows you not to annotate the source)

@Provides @Inject
private BadgerBoy provideBadgerBoy(WeaselCopter copter) {
return new BadgerBoy(copter);

With this provider method, you can use Guice to configure BadgerBoy, and even to select which Vehicle he needs, all without changing BadgerBoy at all. This means that you don't need to use @Inject or binding annotations such as @Fast if you don't want to. You can use provider methods to select your dependencies instead.
Which technique you choose depends on your personal preference, whether you're using third-party classes, and how tightly you want to tie a class to its dependencies. Provider methods allow the totally hands-off approach. Annotated dependencies allow configuration information to live a little closer to the class, which makes the source more comprehensible while preserving flexibility and testability. Your application will likely use both ways to specify dependencies as the circumstance warrants.
You're sick of sending Frog Man on every adventure. You'd like a random hero for each new escapade. However, Guice's default binder API doesn't allow a call like "bind the Hero class to a different implementation each call." However, you can tell Guice to use a special method to create every new Hero. Listing 15 shows a new method added to the HeroModule, annotated with the special @Provides annotation:


リスト15. プロバイダをカスタム生成ロジックのために利用する(Using a provider to write custom creation logic)

private Hero provideHero(FrogMan frogMan, WeaselGirl weaselGirl) {
  if (Math.random() > .5) {
    return frogMan;
  return weaselGirl;

Guice automatically discovers all methods in your Modules that have the @Provides annotation. Based on the return type of Hero, it works out that when you ask for a hero, it should call this method to provide it. You can stuff provider methods with logic to construct your object, pick it randomly, look it up from a cache, or obtain it by other means. Provider methods are an excellent way to integrate other libraries into your Guice module. They're also new as of Guice 2.0. (The Guice 1.0 way was to write custom provider classes, which were clunkier and more verbose. If you've decided to use Guice 1.0, the user's guide has documentation on the old way, and the sample code supplied with this article has a custom provider you can look at.)
Guice automatically injects the provider method in Listing 15 with the correct arguments. This means Guice will find WeaselGirl and FrogMan from its list of bindings without you needing to construct them manually within the provider method. This illustrates the "it's turtles all the way down" principle. You rely on Guice to provide your dependencies, even when you're configuring your Guice module itself.
Asking for a Provider instead of a dependency
Suppose you want multiple heroes in one story ― a Saga. If you ask Guice to inject a Hero, you'll get only one. But if you ask for a "provider of heroes," you can create as many as you like, as in Listing 17:

それらはまた、Guice2.0の新機能でもあります(Guice1.0の方法は、よりclunkier でverboseなカスタムプロバイダクラスを書くことでした。もし、Guice1.0を使ることを決めるなら、ユーザーガイドにその古い方法が記載されています。そして、この記事で提供するサンプルコードは、見つけることができる、カスタムプロバイダーを持っています。)
Guiceは、自動的に正しい引数でリスト15のプロバイダメソッドをインジェクトします。これはプロバイダメソッドを使って手動で構築する必要をなくし、Guiceバインディングのリストからイタチガール(WeaselGirl )とフロッグマン(FrogMan)を見つけることを意味しています。

リスト17. インスタンス化を制御するプロバイダーをインジェクトする(Inject a provider to take control of instantiation)

public class Saga {
  private final Provider<Hero> heroProvider;

  public Saga(Provider<Hero> heroProvider) {
    this.heroProvider = heroProvider;

  public void start() throws IOException {
    for (int i = 0; i < 3; i++) {
      Hero hero = heroProvider.get();

Providers also let you delay the retrieval of the heroes until the saga actually starts. This is handy if the hero depends on data that's time- or context-sensitive.
The Provider interface has one method: get. To access the object provided, you simply call the method. Whether or not you get a new object each time, and how that object is configured, depends on how Guice was configured. (See the next section on Scopes for details about singletons and other long-lived objects.) In this case, Guice uses your @Provides method because it's the registered way to construct a new Hero. This means the saga should consist of a mix of three random heroes.
Providers shouldn't be confused with provider methods. (In Guice 1.0, they were considerably harder to tell apart.) Although the Saga gets its heroes from your custom @Provides method, you can ask for a Provider of any Guice-instantiated dependency. If you wanted, you could rewrite FrogMan's constructor according to Listing 18:


リスト18. 依存性の代わりにプロバイダーに問い合わせることができる。(You can ask for a Provider instead of the dependency)

public FrogMan(Provider<Vehicle> vehicleProvider) {
  this.vehicle = vehicleProvider.get();

(Note that you didn't have to change the module code at all.) This rewrite doesn't serve any purpose; it just illustrates that you can always ask for a Provider instead of the dependency directly.

(モジュールのコードはまったく変えていないことに注目してください。) この書き換えはまったく目的はありません。