Guiceのどこがいいか
結局一番はまらないコンテナってことじゃないですかね。
コンテナ以外何も用意されていないので理解が容易なわけです。
設定をコードでかくので、実装とインターフェースが一致してないとかそんな単純なミスは実行時ではなくコンパイル時にわかるわけです。
あと、エラーメッセージがものすごい親切。こんな親切なのは見たことがない。
親切さはバインディングにも現れています。
for(Entry<Key<?>,Binding<?>> e : injector.getBindings().entrySet()){
out.println(e.getValue());
}
これでBinderが取得してtoString()で出力しているだけなのですが、これがすごい。
抜粋 ProviderInstanceBinding[key=Key[type=javax.servlet.http.HttpServletRequest, annotation=[none]], source=com.google.inject.servlet.InternalServletModule.configure(InternalServletModule.java:42), scope=Scopes.NO_SCOPE, provider=RequestProvider] ConstructorBinding[key=Key[type=com.google.inject.servlet.ManagedServletPipeline, annotation=[none]], source=com.google.inject.servlet.InternalServletModule.configure(InternalServletModule.java:99), scope=Scopes.SINGLETON] ConstructorBinding[key=Key[type=hoge.action.New1Action, annotation=[none]], source=hoge.ActionAutoBindModule.bindClass(ActionAutoBindModule.java:83), scope=ServletScopes.REQUEST] ConstructorBinding[key=Key[type=hoge.action.New2Action, annotation=[none]], source=hoge.ActionAutoBindModule.bindClass(ActionAutoBindModule.java:83), scope=ServletScopes.SESSION]
見てわかるとおり、どのクラスがどういったスコープでどういったキーで取得されるのかというのが書かれているんですが、中でも注目すべきはsource。
ソースコードのどこで記述されたかがわかるという優れもの。
こういうはまらないための要素がGuiceはたくさん用意されている。設定にはまってる時間があったらさっさと実装コード書け!というメッセージだと思う。
DIコンテナの流れは数年前からおそらくEJB3のような方向に進んでいるんだと思う。設定ファイルを書く人がバインドする先を細かく指定してあげたり、自動で型や名前でバインドするのではなく、注入箇所を使用する側が適切に指示をする、注入されるというより引き出すという感じ。EJB3の@EJB、Guiceの@Inject、Seasar2の@Binding、Springの@Autowired。(もともとEJB3は仕様決めている途中は注入に@Injectという名前使っていたと思うんだけれども、その名前だったらコモンアノテーションになってたかもしれないなーと思ったり)
そして一番大事なDIコンテナの機能はスコープ管理なんじゃないかな。ライフサイクルの管理から実装者が解放される。もしかするとここが一番重要で、注入とかIOCとかどうでもいいことなのかもしれないと最近思うようになった。そういうのはサービスロケータでもどうにでもなるし、本質が劇的に変わるものではないのかなと。使ったことのない人にとって便利な機能と説明できないし。でもスコープならば割りと体感してくれると思う。シングルトンのアノテーションつけるだけで通常のBeanがシングルトンになるとか、そういうのはわかりやすいはず。
こうなるともうコンテナ自体には差はないと思ってよいことに。
Guiceの最大の利点はコードで書くことによってIDEの標準的な機能さえあれば十分で、特別なサポート用のプラグ印がいらないことじゃないかな。CTRL+SPACEですぐとんだりできるし、型はGenericsでミスすることはないし、すでにあるものはそれを使おうって個人的なイメージがある。