レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

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

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

Guiceによる基本的なインジェクション (Basic injection with Guice)

I hope I've convinced you that DI adds value to your designs and that using a framework will make your life even easier. Let's dive into Guice, starting with the @Inject annotation and modules.


DIが設計に価値を加えることと、フレームワークを使うと日常的な開発が簡単になることについて、あなたを説得したいと思います。
では、@Injectとモジュールを手始めに、Guiceに飛びこんでいきましょう。

クラスに@Inject-edが必要だとGuiceに教える (Tell Guice you want your class @Inject-ed)

The only difference between FrogMan and FrogMan on Guice is @Inject. Listing 5 shows FrogMan's constructor with the annotation:


FrogMan」と「GuiceでのFrogMan」の違いは、@Injectアノテーションです。リスト5はアノテーションを付けたFrogManのコンストラクタです。


リスト5. @InjectされたFrogMan(FrogMan has been @Injected)

@Inject
public FrogMan(Vehicle vehicle) {
  this.vehicle = vehicle;
}

※訳注 @Injectにハイライト


Some engineers dislike the idea of adding an @Inject to their class. They prefer that a class be totally ignorant of the DI framework. This is a reasonable point, but I'm not convinced by it. As dependencies go, an annotation is pretty mild. The @Inject tag takes on meaning only when you ask Guice to construct your class. If you don't ask Guice to create FrogMan, the annotation has no effect on the code's behavior. The annotation provides a nice clue that Guice will participate in the construction of the class. However, using it does require source-level access. If the annotation bothers you or you're using Guice to create objects whose source you don't control, Guice has an alternate mechanism (see the Other uses for provider methods sidebar later in the article).


エンジニアの仲には、@Injectアノテーションをクラスに記述するのを嫌がる人もいます。
彼らは全体的にDIフレームワークに依存しない事のほうを好むのです。これは、もっともなことです。しかし私はそれでは納得できません。依存性があることに比べればアノテーションはかなり軽いものです。@Injectタグは、Guiceにクラスを生成するように命令したときにだけ意味をもちます。もし、FrogManを生成するようにGuiceに命令しなければ、アノテーションはコードの動きにまったく影響ありません。アノテーションは、Guiceがクラスの生成に参加することを示す良い手掛かりを提供します。しかしながら、それはソースレベルでの記述を必要とします。もし、あなたがコントロールできないソースのアノテーションが、オブジェクト作成にGuiceを使用することを苦しめるならば、Guiceには代替のメカニズムがあります(後述するプロバイダーメソッドサイドバーへの別用途を参照)。

Tell Guice which dependency you want

Now that Guice knows that your hero needs a Vehicle, it needs to know which Vehicle to provide. Listing 6 contains a Module : a special class that you use to tell Guice which implementations go with which interfaces:


ここまでで、Guiceはあなたのヒーローが乗り物を必要とすることを知りました、どういった乗り物が提供されるかをしることが必要です。リスト6にはモジュールが記載されています。これは、どの実装クラスがどのインターフェイスに設定されるのかをGuiceに対して知らせるために使う特別なクラスです。


リスト6.ヒーローモジュールで乗り物に対してフロッグモービルを紐付けする。(The HeroModule binds Vehicle to FrogMobile)

public class HeroModule implements Module {
  public void configure(Binder binder) {
    binder.bind(Vehicle.class).to(FrogMobile.class);
  }
}


A module is an interface with a single method. The Binder that Guice passes to your module lets you tell Guice how you want your objects constructed. The binder API forms a domain-specific language (see Resources). This minilanguage lets you write expressive code such as bind(X).to(Y).in(Z). You'll see more examples of what the binder can do as we proceed. Each call to bind creates a binding, and the set of bindings are what Guice uses to resolve injection requests.


モジュールは、一つだけのメソッドを持つインターフェイスです。Guiceがモジュールに渡すBinderは、Guiceに対してどのようにオブジェクトを生成するかを伝える手段を提供します。binderのAPIドメイン特化言語(domain-specific language)の書式を取っています(参照)。これは、たとえば「bind(X).to(Y).in(Z)」のような表現力豊かなコードを書くことができる小型言語です。binderがどのようなことができるのかを照会するサンプルは、この記事を進めていくとより多く見ることができます。バインディングを生成するどの呼び出しでも、Guiceがインジェクションを要求することで解決します。
バインドするための各呼び出しはバインディング、およびバインディングのセットを作成します。そして、それらをGuiceがインジェクション要求を解決するのに使用します。

Injectorによるブートストラップ(Bootstrap with an Injector)

Next, you bootstrap Guice using the Injector class. Typically you want to create your injector very early in your program. This lets Guice create most of your objects for you. Listing 7 contains an example main program that starts a heroic adventure using an Injector:


次にInjectorクラスを使ったGuiceの起動コードを見てみましょう。典型的にはプログラムの一番初めの方でInjectorを生成します。
これは、Guiceにできるだけたくさんのオブジェクトを生成させるためです。リスト7は、Injectorを使った「ヒーローの冒険」を開始するメインプログラムのサンプルです。


リスト7 Injectorを使ったアプリケーションの起動コード(Bootstrapping your application with an Injector)

public class Adventure {
  public static void main(String[] args){
    Injector injector = Guice.createInjector(new HeroModule());
    FrogMan hero = injector.getInstance(FrogMan.class);
    hero.fightCrime();
  }
}


To get an injector, you call createInjector on the Guice class. You pass createInjector a list of modules it should use to configure itself. (This example has only one, but you could add a VillainModule that configures evildoers.) Once you have the injector, you ask it for objects with getInstance, passing in the .class you'd like to get back. (Astute readers will notice that you don't need to tell Guice about FrogMan. It turns out that if you ask for a concrete class, and it has an @Inject constructor or public no-argument constructor, Guice creates it without needing a call to bind.)


Injectorインスタンスを取得するためには、GuiceクラスのcreateInjectorメソッドを呼び出します。
createInjectorにモジュールのリストを引き渡せば、モジュールの設定を利用することができます。
(この例ではモジュールは1つだけですが、"邪悪なる者(evildoers)"を設定した"悪党モジュール(VillainModule)"などを追加することもできます。)
ひとたびInjectorを手に入れれば、getInstanceメソッドに".class"を渡すことによって、オブジェクトを取り出したいときに取り出すことができます。
(抜け目のない読者は、Guiceに対してFrogManのことを伝える必要がないということに気づいていることでしょう。また、コンクリートクラスを問い合わせた場合、そしてそのクラスが@Injectコンストラクタか、または引数の無いパブリックコンストラクタを持っているなら、Guiceはバインドを呼び出す必要なしにそれを生成するということがわかります。)


This is the first way of getting Guice to construct your objects: asking explicitly. However, you don't want to do this outside of your bootstrapping routine. The better, easier way is to have Guice inject your dependencies, and the dependencies' dependencies, and so on. (As the saying goes, "it's turtles all the way down"; see Resources). This will seem disconcerting at first, but after a while you'll get used to it. As an example, Listing 8 shows the FrogMobile having its FuelSource injected:


明示的に問い合わせることは、オブジェクトを構築してGuiceから取得する第1番目の方法です。
しかしながら、起動ルーチンの外側でこのようなことをやりたくないと思うかもしれません。
より良くて、簡単な方法は、Guiceに依存性や、依存性の依存性や、その他諸々を注入させることです。
(いわば、"亀が地球を支えている"ってやつです参照)。
これははじめのうちは混乱するように思えるでしょうけれど、しばらく使ってれば慣れてきます。
リスト8のサンプルは、フロッグモービルが燃料を注入されるところを表しています。


リスト8. フロッグモービルが燃料を受け取る(The FrogMobile accepting a FuelSource)

@Inject
public FrogMobile(FuelSource fuelSource){
  this.fuelSource = fuelSource;
}


This means that when you retrieve FrogMan, Guice constructs a FuelSource, a FrogMobile, and then finally a FrogMan, even though your application interacted with the injector only once.


これはFrogManを取得するときにGuiceが"燃料(FuelSource)"と"フロッグモービル(FrogMobile)"を生成し、それから最後にFrogManを生成することを表しています。あなたのアプリケーションがたった1度だけInjectorとやり取りするにもかかわらずです。


Of course, you don't always get the chance to control your application's main routine. Many Web frameworks, for example, automagically construct "actions," "templates," or something else that serve as your starting point. You can usually find a place to shim Guice in, either with a plug-in for the framework or some handwritten code of your own. (For example, the Guice project has released a plug-in for Struts 2 that lets Guice configure your Struts actions; see Resources.)


もちろん、いつでもアプリケーションのメインルーチンのコードを書き換えられるというわけではないでしょう。
たとえば多くのWebフレームワークでは、自動的に"actions"や"templates"やその他のものをスタートポイントとして生成して提供してくれます。
通常、フレームワークプラグインや独自の手書きのコードを使わずとも、Guiceを組み込むための場所を見つけることができます。(たとえば、GuiceプロジェクトはStruts2のためのプラグインをリリースしています。これはStruts Actionの設定をGuiceにさせるためのものです。(参照))