Google Guice(その1) 概要
以前同僚のM君より存在を教えてもらったGoogleのDIコンテナGuiceですが、めでたく1.0になったようなのでちょっと見てました。
一言で言うと、「アノテーションとジェネリクスを使い、パフォーマンスを重視し、DIに特化したDIコンテナ」のようです。
とりあえず、「何で新しくDIコンテナ作ったの?」「Springとの違いは?」というのが万人共通の疑問だと思うので、まさにそれに答えているページをまず見てみました。
http://code.google.com/p/google-guice/wiki/SpringComparison
より。記述順序や訳はかなりいい加減なので、ちゃんと読みたい方は上記URLを参照下さい。
- 発音:「ジュース」*1
- Springについて
- Guice全般
- アノテーションについて
- 「アノテーションが増えると収拾つかない」と心配する人もいるが、大丈夫。Springアプリで定義しているほど、アノテーションは多くならない
- Guiceは、明示的なコンフィギュレーション(面倒だけど大きいプロジェクトでは必須)と、AutoWiring*4(簡単だけど小さいプロジェクトでしか使えない)の、両方のシチュエーションにピッタリ。アノテーションによって、簡単だけど明瞭でメンテナンス性が高い
- サードパーティのコンポーネントを使う場合などはアノテーションが使えず、手動でwireしなければならない。そんな時はカスタムプロバイダを書けば一階層挟む事ができて、そうやってだいたいSpringのXMLと同じくらいの複雑さだ。その他の、殆どの場合はかなり少ない記述でOK
- AOPについて
*1:これは http://code.google.com/p/google-guice/ に記載
*2:ベンチマークコード⇒http://google-guice.googlecode.com/svn/trunk/test/com/google/inject/PerformanceComparison.java
*3:これはサンプル見ないと何を言ってるのかよく分かりませんね。少なくとも私は…
*4:型で一致したりする例のやつ
*5:ここ自信なし…
Google Guice(その2) 最も単純にInjectするサンプル
一番単純なサンプルを、ユーザガイドから少し変えて書いてみます。あ、このドキュメントGoogle Docsだ。
構成は以下。
- Service
- Injectするインタフェース
- ServiceImpl
- Injectするインタフェースの実装クラス
- Client
- ServiceがInjectされるクラス
- Main
- 起動クラス
まずServiceとServiceImpl。
public interface Service { String getResponse(String msg); }
public class ServiceImpl implements Service { public String getResponse(String msg) { return "Re: " + msg; } }
当たり前ですが、POJOです。そしてServiceを呼び出すClient。
import com.google.inject.Inject; public class Client { @Inject private Service service; public void execute() { String response = service.getResponse("Hello"); System.out.println(response); } }
もう、どう見てもserviceをInjectする気満々ですね。「どこにInjectするか」は、アノテーション@Injectで指定するようです。
さて一番知りたいのは、何をするとこれがInjectされるのか。
public class Main { public static void main(String[] args) { Injector injector = Guice.createInjector(new MyModule()); Client client = injector.getInstance(Client.class); client.execute(); } static public class MyModule extends AbstractModule { @Override protected void configure() { bind(Service.class).to(ServiceImpl.class); } } }
これだけでした。気になっていた部分は、
bind(Service.class).to(ServiceImpl.class);
で、今回の例では、bind(インタフェース).to(実装クラス) で「何をInjectするか」を設定しています。SpringだとXMLに
という事で、実行するとめでたく
Re: Hello
と表示されました。