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.


クラスに@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:


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

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).


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:


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

public class HeroModule implements Module {
  public void configure(Binder binder) {

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がインジェクションを要求することで解決します。

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:


リスト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);

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.)


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:


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

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.


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.)

通常、フレームワークプラグインや独自の手書きのコードを使わずとも、Guiceを組み込むための場所を見つけることができます。(たとえば、GuiceプロジェクトはStruts2のためのプラグインをリリースしています。これはStruts Actionの設定をGuiceにさせるためのものです。(参照))