Springとの比較
Rod JohnsonによるSpringフレームワークはJava-DI界で大人気である。 最初のDIフレームワークとは言わないまでも、DIのパイオニアであり、DIをメインフレームにした功労者と言えるだろう。 Springが無ければGuiceも(少なくともこんなに早くには)存在しなかっただろう。
GuiceとSpringは直接的には競合しない。 Springは総合的なスタックであり、GuiceはDIに特化している。 そうであっても、人々の最初の質問は「GuiceとSpringの違いは?」である。 何度も熱弁をふるうよりも、この避けがたい質問に一度だけ答えておくのがよいだろう。
GuiceチームはSpring開発者やコミュニティ、その姿勢に多大なる尊敬の念を持つことをまず言わせてもらいたい。 我々はいかなる形態であっても、共に仕事をしたいと思う。 実は1.0のリリースの六ヶ月前に、数人のコアなSpring開発者に内密にソースまで公開したのである。
さて、さっさと本題に入ろう。GuiceとSpringがどのように違うのか?
GuiceはSpringの焼き直しなどではない。 GuiceはGoogleの(いかなる意味でも)最も大きなアプリケーション「アドワーズ」のユースケースから誕生した。 我々は自問自答した、このアプリを前進させるために、本当に欲しいものは何かと。 Guiceが我々の答えをもたらしたのである。
Guiceは全面的にアノテーションとジェネリックスを取り入れている。 それゆえ、オブジェクトをワイアリング、テストするための労力が計れる程度には減少する。 Guiceは、エラーになりがちでリファクタリングに不都合な文字列識別子の代わりにアノテーションを使用できることを証明した。
新しいユーザはアノテーションが多くなりすぎて手に負えなくなることを恐れることがある。 大丈夫、Springアプリケーションで使う文字列識別子と同程度のアノテーションの数にしかならない。
- 一つの型についてのバインディングが一つでは不十分な場合にだけアノテーションが必要になる。
- 複数のバインディングで、同じアノテーションタイプを再利用することができる(例えば@Transactional)。(訳注:?)
- アノテーションは値付のアトリビュートを持つことができる。望むならそれぞれの値セットを一つのタイプについて別々にバインドすることができる(訳注:?)。
Springは二つの正反対なコンフィギュレーションスタイルを持つ。 明示的なコンフィギュレーションとオートワイアリングである。 明示的コンフィギュレーションは冗長であるがメンテナンスしやすい。 オートワイヤリングは手軽だが遅い上、比較的大きなアプリにはうまく適合しない。 もし、100人の開発者による数十万行のコードであれば、オートワイヤリングは選択できない。 Guiceはアノテーションを使うことにより、二つの世界のベストなアプローチをサポートすることができる。 つまり、手軽でかつ明示的(そしてメンテナンスしやすい)である。
Guiceに、SpringのXML(あるいは新しいJavaベースのコンフィギュレーション)との類似性を見出そうとする評論家もいる。 大抵の場合は全然ないが、しかしアノテーションが使えないケースもある。 そのときはマニュアルでワイヤアップしなければならないサードパーティ製コンポーネントなど)。 その際にはカスタムプロバイダを記述することになるだろう。 カスタムプロバイダは、あなたのコンフィギュレーションに一つ上のレベルの「間接」を持ち込むことになり、それはSpringのXMLと複雑さにおいてだいたい1:1対応していると考えられる。 しかし、他の多くの場合には(Springに比較して)著しく少ないコードで済むはずだ。
Eric Burkeは最近SpringアプリケーションをGuiceに移植した。
その日の最後に、私がJavaで記述した(Guiceの)モジュールと私のSpring XMLファイルを比較してみました。 モジュールの方がとても小さくて読みやすかったのです。 そして私は、そのモジュールの3/4は不必要であると感じ、それらを削除しました。 それぞれ、数行のコードに縮まりました。
すぐにGuiceに移行したくもないのに、完全に動作しているコードを移植するのは意味のないことだろう。 Guiceは、可能な場合にはSpringと協調動作することもできる。 既存のSpringビーンをバインドすることができるし、 GuiceはAOPアライアンスのメソッドインターセプターをサポートしているので、Springで人気のトランザクションインターセプターを使うことができるのだ。
我々の経験から言うと、多くのAOPフレームワークは大抵の場合はパワフルすぎ、その複雑な概念が伝わっていないと思う。 Guiceは、後からの思いつきではなく、そのコア部分にメソッドインターセプションを組み込んでいる。 これによって、AOPのメカニクスをユーザから隠し、ラーニングカーブを下げている。 分離されたプロキシの代わりに単にオブジェクトを使用することによって、メモリの無駄を省くが、さらに重要なことはインターセプター無しにメソッド呼び出しができることだ。 水面下では、パフォーマンスオーバヘッドを下げるために、Guiceはそれぞれのメソッドに対する別のハンドラを使っている。 クラス内のただ一つのメソッドをインターセプトするために、他のメソッドまでその影響を受けるということはない。