Guice(ジュースと読む)は,GoogleのエンジニアBob Lee氏(ブログ)などによって開発されたDIフレームワークです。バージョン1.0が2007年3月8日にApache License 2.0の下で公開されました(公開時のブログ)。実行環境としてJava 5が必要です。
DIとは依存性の注入(Dependency Injection)のことで,同じインターフェースを持つ具象クラスを,設定によって入れ替え可能にする方法を指し,IoC(Inversion of Control - 制御の反転)と呼ばれることもあります。これにより,たとえばテスト用のモッククラスと,実際の業務ロジックが組み込まれたクラスとの,必要に応じた入れ替えがしやすいというメリットがあり,システム開発の生産性を向上させる技術して注目されています。同様のしくみを持つものとして,Spring Framework,PicoContainer,NanoContainer,S2Container(Seasar2)などがあります。
DIフレームワークは,あるインターフェースを持つクラスのインスタンスを生成する際,具象クラス(依存性)を注入する処理を行います。そのため,事前にインターフェースに対してどの具象クラスを対応させるかを設定しておく必要があります。フレームワークによって,設定をXMLファイルに記述するか,Javaクラスで実行するかが異なりますが,Guiceは後者に分類できます。つまり,GuiceはXMLファイルを利用しないDIフレームワークです。
Guiceのダウンロード
Guiceのバイナリモジュールはguice-1.0.zipですが,ファイル名はバージョンアップにより変更される可能性があります。これを展開すると複数のJARファイルやJavadocなどが生成されます。Guiceを用いたアプリケーションをコンパイルおよび実行する際は,展開されたJARファイルをCLASSPATHに加えておいてください。
ソースコードは,GuiceのWebサイトから「Downloads」をクリックしたあとの画面よりguice-1.0-src.zipをダウンロードできます。こちらもファイル名はバージョンアップにより変更される可能性があります。
それでは,実際にGuiceを味わうことにしましょう。
基礎編
ここでは基礎編として,インターフェースと具象クラスとを対応させるDIの設定から,インスタンスを生成するまでの一連の流れを紹介します。
DIの設定
GuiceによるDIの設定は以下の手順で行います。これらは他のDIフレームワークとほぼ同様で,それほど特殊な方法というわけではありません。
- 1) インターフェースを作成する
- 2) 具象クラス(依存性のもと)を作成する
- 3) 1)と2)とを対応させる(DIの設定をする)モジュールを作成する
- 4) 2)を実行するためのクラスを作成する
1) インターフェースを作成する
まず,例としてPlayインターフェースを作成します(リスト1)。これにはplay()というメソッドの宣言を記述しておきます。メソッドの中身は2)で作成する具象クラスに実装します。
リスト1 インターフェースの作成
public interface Play {
// メソッドの中身は具象クラスで実装する
void play();
}
2) 具象クラス(依存性のもと)を作成する
1)で作成したインターフェースを実装した具象クラスを作成します(リスト2-1)。DIフレームワークでは,このクラスを直接実行するのではなく,依存性を注入するための入れ替え用のクラスとします。play()メソッドでは,簡単なメッセージを表示させることにします。このとき,リスト2-2やリスト2-3のような別の具象クラスも用意しておくと,注入する依存性を入れ替えるしくみが理解しやすいでしょう。いずれも1)で作成したインターフェースを実装しています。
なお,クラスをstaticで宣言しているのは,インスタンスを生成していなくてもDIの設定をできるようにするためです。
リスト2-1 1)のインターフェースを実装した具象クラス
// 設定時に参照できるようにstaticにしている
static class PlayImpl implements Play {
// 実装されたメソッド
public void play() {
System.out.println( "何かしてあそぶ!" );
}<
}
リスト2-2 別の具象クラスの例(1)
static class Baseball implements Play
public void play() {
System.out.println( "野球してあそぶ!" );
}
}
リスト2-3 別の具象クラスの例(2)
static class Soccer implements Play {
public void play() {
System.out.println( "サッカーしてあそぶ!" );
}
}
3) 1)と2)とを対応させる(DIの設定をする)モジュールを作成する
1)で作成したインターフェースと,2)で作成した具象クラスとを対応させるクラスを作成します。これにより,Playインターフェースを持つインスタンスが要求された場合に,2)で作成した具象クラス(依存性)のインスタンスが注入されるようにします。
Guiceでは,ここで作成するクラスをモジュールと呼び,com.google.inject.AbstractModuleクラスを継承して作成します。実際の処理はconfigure()メソッドに記述します。
リスト3 インターフェースと具象クラスとを対応させるモジュール
class PlayModule extends AbstractModule {
protected void configure()
// PlayImplクラスを対応させる(この場合はSingletonとする)
bind( Play.class ).to( PlayImpl.class ).in( Scopes.SINGLETON );
// 別の具象クラスを対応させる場合(例)
// bind( Play.class ).to( Baseball.class ).in( Scopes.SINGLETON );
// bind( Play.class ).to( Soccer.class ).in( Scopes.SINGLETON );
}
}

