2009年11月2日月曜日

Google Guiceを使ってみた

このエントリーをはてなブックマークに追加
Google Guice はオープンソースの Java™ 開発用DI (Dependency Injection: 依存性注入)フレームワークです.

DIとは依存性の注入のことで,同じインターフェースを持つ具象クラスを,設定によって入れ替え可能にする方法を指します.このことにより,プログラムの挙動を動的に変更することができます.

[download]
http://code.google.com/p/google-guice/downloads/list

[Main.java]
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;

public class Main {
 public static void main(String[] args) {
  Injector injector = Guice.createInjector(new AbstractModule() {
   @Override
   protected void configure() {
    bind( String.class ).toInstance( "まつたけ" );
    bind( int.class ).toInstance( 5000 );
   }
  });
  injector.getInstance(Item.class).view();
 }
}

[Item.java]
import com.google.inject.Inject;

public class Item {
 @Inject
 private String name;
 @Inject
 private int price;
 
 public void view() {
  System.out.println("商品名" + " : " + name);
  System.out.println("値段" + " : " + price);
 }
}

上記のプログラムでは,次の2行でItemクラスのフィールドに対して値を代入しています.
bind( String.class ).toInstance( "まつたけ" );
bind( int.class ).toInstance( 5000 );

ここでは,Itemクラスのフィールドの型が別なので,自動的にString型がnameへintがpriceに代入されています.

ここで,Itemクラスに商品番号を表すint idというフィールドがあった時,どちらを代入すればよいのかわからないため,例外が飛びます.
bind( int.class ).toInstance( 5000 ); // price?
bind( int.class ).toInstance( 1 );  // id?

そのとうな場合には,下記のようにアノテーションで名前をつけることにより,解決できます.

[Main.java]
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;

public class Main {
 public static void main(String[] args) {
  Injector injector = Guice.createInjector(new AbstractModule() {
   @Override
   protected void configure() {
    bind( String.class ).annotatedWith(Names.named( "name" )).toInstance( "まつたけ" );
    bind( int.class ).annotatedWith(Names.named( "price" )).toInstance( 5000 );
    bind( int.class ).annotatedWith(Names.named( "id" )).toInstance( 1 );
   }
  });
  injector.getInstance(Item.class).view();
 }
}

[Item.java]
import com.google.inject.Inject;
import com.google.inject.name.Named;

public class Item {
 @Inject
 @Named("name")
 private String name;
 @Inject
 @Named("price")
 private int price;
 @Inject
 @Named("id")
 private int id;
 
 public void view() {
  System.out.println("商品名" + " : " + name);
  System.out.println("値段" + " : " + price);
  System.out.println("ID" + " " + id);
 }
}


参考:
Guice による依存性注入(IBM Developerworks)
http://www.ibm.com/developerworks/jp/java/library/j-guice.html

GoogleからリリースされたDIフレームワーク(gihyo.jp)
http://gihyo.jp/dev/serial/01/awdp/000101


GoogleのDIフレームワーク"Guice"を使ってみる(マイコミジャーナル)
http://journal.mycom.co.jp/articles/2007/03/14/googleguice/001.html