レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

Guice vs. SpringJavaConfig (5) Conclusions

Conclusions

Both Guice and Spring JavaConfig offer interesting alternatives to the sometimes verbose XML used to configure many frameworks (including Spring). Each, however, takes a different approach to configuration. Let's examine how they stack up against each other:


まとめ
GuiceとSpring JavaConfigは、共に面白い提案をしています。その提案とは、多くのフレームワーク(Springを含む)で設定に使われている時に冗長なXMLへの代替案です。どちらも、しかしながら設定方法としては違ったアプローチを取っています。さぁ、お互いの比較をよく見てみましょう。

  • String identifiers - One complaint against Spring's XML configuration is the use of String identifiers and the lack of refactorability therein. It's true, that Spring's XML configuration is heavy with references to classes, properties, and other beans that are merely String values and thus difficult to refactor without a proper tool (such as the SpringIDE for Eclipse). Fortunately, both Guice and Spring JavaConfig register a win in this category, as neither relies on String identifiers in their configuration and both are easily refactorable through modern IDEs.

  • 文字列による識別子 SpringのXML設定ファイルに対する1つの批判は、文字列による識別子を使っていることと、そのことによってリファクタリングのしやすさが損なわれていることです。確かに、SpringのXMLコンフィグファイルは、クラスやプロパティーそれから他のBeanを参照するのが面倒です。ただ単なる文字列値であり、それゆえに適切なツール(EclipseのSpringIDEのような)を使わない場合にリファクタリングが難しくなっています。幸いにも、GuiceとSpring JavaConfigは共にこのカテゴリーに対しては効き目があります。両方とも、それらのコンフィグレーションにおいて文字列による識別子に頼らず、最近のIDEを使えば簡単にリファクタリングできるようになっています。


  • Speed/Performance - Guice bills itself as faster than other containers when performing dependency injection. While I didn't run any formal benchmarks to compare Spring JavaConfig and Guice, some informal tests proved Guice's claims to be true. This is not terribly surprising, however, as Spring defines a rich set of lifecycle events around the creation of beans in the container, while I could not find any comparable lifecycle built into Guice. Without the overhead of the lifecycle events, Guice does, in fact, wire up the beans much faster than Spring.

  • スピード/パフォーマンス GuiceDependency Injectionの処理について他のコンテナよりも速いと自分で宣伝しています。あらゆる公式のベンチマークではかったわけではないですが、Spring JavaConfigとGuiceを比較したところ、いくつかの非公式テストではGuiceの主張が正しいことがわかりました。これは、それほど驚くことでもありません、しかしながら、Springは、コンテナでBeanを生成することに関する豊富なライフサイクルイベント郡をもっています。Guiceでは、これに相当する機能をみつけることができませんでした。ライフサイクルイベントのオーバーヘッドがないので、Guiceは、実際のところ、Beanの紐付けがSpringよりも速いです。


  • JAR file footprint - The Guice example above only requires two JAR files: guice-1.0.jar and aopalliance.jar. Together, these two JAR files weigh in at just over half a megabyte. Meanwhile, the Spring example requires several JAR files, including spring-javaconfig.jar, spring-beans.jar, spring-aop.jar, spring-core.jar, spring-context.jar, commons-logging.jar, aopalliance.jar, asm-2.2.2jar, cglib-nodep-2.1_3.jar, and aspectjweaver.jar, together weighing in at several megabytes in size. So, Guice is more lightweight than Spring in terms of JAR file footprint.

  • JARファイル足跡 前述のGuiceのサンプルでは、 guice-1.0.jar と aopalliance.jar のたった二つのJARファイルだけが必要でした。それらの2つのJARファイルは、重量も500KByteほどしかありません。一方Springのサンプルは、いくつかのJARファイルを必要とします。それらは、spring-javaconfig.jar, spring-beans.jar, spring-aop.jar, spring-core.jar, spring-context.jar, commons-logging.jar, aopalliance.jar, asm-2.2.2jar, cglib-nodep-2.1_3.jar, and aspectjweaver.jarです。それらのいくつかはメガ単位のサイズです。それで、GuiceはJARファイルの点ではSpringよりも軽量です


  • Non-intrusive - Both Spring JavaConfig and Guice rely on proprietary annotations to help them do their injections. Where they differ, however, is that Guice requires placement of @Inject annotations withing the injected application classes, while Spring JavaConfig confines its use of annotations to the configuration-specific classes. Consequently, Guice-injected classes cannot be reused and compiled in a separate application without the Guice JAR file in place. Meanwhile, Spring JavaConfig leaves the application classes unaltered, enabling their unhindered reuse. Thus, in this category, Spring JavaConfig is the clear winner. (Granted, Spring does define a handful of annotations to be placed in application classes--@Required and @Transactional come to mind. But their use is not mandated to configure Spring.)

  • 煩わしくない Spring JavaConfigとGuiceの両方で、インジェクトを補助するために独自仕様のアノテーションに依存します。しかしながら、Spring JavaConfigとGuiceのそれぞれの違いは、Guiceは@Injectアノテーションをインジェクトされるアプリケーションクラスと一緒に配置しなくてはならないのに対して、Spring JavaConfigはアノテーションの使用をコンフィグレーション特有のクラスに制限します。その結果Guiceを使った場合、異なるアプリケーションで、Guice JARファイルを配置せずにはインジェクトされたクラスを再利用のためにコンパイルすることができません。そうしてる間に、Spring JavaConfigはアプリケーションクラスを変更せず残します、そのため再利用を妨害しません。したがって、このカテゴリでは、Spring JavaConfigの完勝です。(与えて、Springはアプリケーションクラスに配置されるいくつかのアノテーションを定義しています。たとえば、@Requiredや@Transactionalが思い浮かびます。 しかし、それらはSpringを使わなくても利用可能です)


  • Third-party beans - Related to the last category, I could find no direct way to inject values into a third party class using Guice. Guice-style injection requires the use of the @Inject annotation, which is useless in classes for which I do not have the source code (or classes that I do not wish to annotate with @Inject). Guice's documentation indicates that third-party components will require the creation of a custom provider, but in my opinion, this is a hack that adds complexity to something that would be very simple if the @Inject annotation were not required. Spring JavaConfig, however, keeps the configuration separate from the application classes, thus wiring a third-party class in Spring JavaConfig is no different than wiring a custom class. Spring wins again.

  • サードパーティーのBean 最後のカテゴリーにも関連しますが、Guiceを使ってサードパーティーのクラスに値をインジェクトする直接的な方法を見つけることができませんでした。Guice方式のインジェクションは、@Injectアノテーションの利用を必要とします。そのため、ソースコードを持っていないようなクラス(または、@Injectでアノテートしたくないようなクラス)に対しては役に立ちません。Guiceのドキュメントは、サードパーティーコンポーネントを使う場合は、カスタムプロバイダーを作ることを必要とすると記述しています。しかし、私の意見として、この方法は、もし@Injectアノテーションが必要でなかったとしても、とてもシンプルにしたいものに対しても複雑さを増してしまいます。しかしながらSpring JavaConfigでは、コンフィグレーションをアプリケーションクラスから分離しています。それゆえに、Spring JavaConfigを使ってもサードパーティーのクラスへの紐付けを使うことは、カスタムクラスに対して紐付けを使うことに対して、ぜんぜん違いはありません。Springが、またも勝利です。


  • Constant/literal injection - Injecting a String literal (or any other type of literal value) in Spring JavaConfig is rather straightforward. In contrast, literal injection in Guice is cumbersome, requiring the creation and use of a custom annotation to identify where the literal should be injected. Spring JavaConfig wins this category.

  • コンスタント/リテラル インジェクション Spring JavaConfigにおいて文字列のリテラル(およびその他の型のリテラル値)をインジェクトすることは、より素直です。それに引き換え、Guiceでのリテラルのインジェクションは、リテラルがインジェクトされる場所を識別するためにカスタムアノテーションを使うという、創作を必要とするので扱いにくいのです。このカテゴリーではSpring JavaConfigの勝ちです。


  • AOP - The Guice documentation acknowledges that Guice's flavor of AOP is less powerful than Spring AOP (both of which are much less powerful than AspectJ). But, the Guice documentation claims that this loss of AOP power is in trade for simplicity. Honestly, I found Guice's approach to AOP (binding interceptors) non-intuitive as compared to Spring JavaConfig. The Spring JavaConfig approach required only a simple annotation with an AspectJ-style pointcut expression, whereas Guice required a confusing binding call involving "matchers" to pick out the target of the interceptor. Maybe I'm too well-versed in Spring AOP to appreciate the simplicity of Guice's interceptor-binding...but for now I must give Spring the win in this category.

  • AOP Guiceのドキュメントは、GuiceAOPは、SpringAOPよりパワーは劣ると認めています。(AspectJAOPに対しても劣ります)しかし、Guiceのドキュメントは、AOPのパワーのロスはシンプルさとのトレードだと主張しています。正直に、私はGuiceAOPのアプローチ(インターセプターのバインド)は、Spring JavaConfigに比べて直感的ではないと思いました。Spring JavaConfigのアプローチは、シンプルなアノテーションを要求するだけです。そのアノテーションとは、AspectJ方式のポイントカットの記述式を使います。それに対して、Guiceはインターセプターの対象を見つけ出すための"matchers"を伴う、分かりにくいバインディングの呼び出しを必要とします。たぶん、Guiceのインターセプターバインドのシンプルさに価値を認めるためには、私はSpringAOPに精通しすぎています。しかし、このカテゴリーではSpringに勝利を与えざるを得ません。

Final score: Guice - 3, Spring JavaConfig - 5.


最終的なスコア: Guice-3、Spring JavaConfig-5

I'm glad that I spent the time to learn a little about Guice, but I'm not all that "juiced" about using Guice. In addition to all of the reasons given above, I'd much rather build my application against a well-established container like Spring that has a wealth of integration points with other frameworks and APIs (Guice only has integration with Struts 2 and Spring, as far as I can tell). Also, to be clear, Guice really doesn't compete with Spring as much as it competes with Spring's application context--Spring's capabilities go beyond dependency injection and AOP.


私はGuiceに関して少し学ぶ時間を過ごせたことをうれしく思います。しかし、Guiceを使用することでは、それほど「Juice」を絞られませんでした。上記に示した、すべての理由に加えて、私は私のアプリケーションを構築するのに、むしろSpringのように地位を確立していて、他のフレームワークと豊富な統合ポイントを持っているAPIをもつコンテナを使ってアプリケーションを構築するでしょう。(Guiceには、私が判断することができる限りStruts2とSpringとの統合があるだけです)。 またはっきり言って、Guiceは実はSpringと、Springのアプリケーションコンテキストと競合するというほどでもありません--Springの能力はDependency InjectionとAOPを越えています。

Also, one more comment on the speed issue: I've given Guice a point in that category, simply because my quick-n-dirty tests confirmed that Guice was faster. But, I've seen a few more detailed performance tests run by others that show that while Guice is faster in creating prototype beans, Spring is faster in creating singletons. Given that singletons are more typically used than prototypes, Spring should probably get the point in this category. But since I have not taken the time to provide the evidence, I'll go ahead and give this one to Guice.


スピードの問題に、もうひとつのコメントを加えます。単に私の、即興で信頼できないテストでは、Guiceの方が速いと確認したので、そのカテゴリではポイントをGuiceに与えました。 しかし、私は、他の詳細な性能テストを走らせたところ、GuiceはプロトタイプBeanを作成している間に、より速いSpringはシングルトンを作るのにより速いのを示すものがありました。シングルトンがプロトタイプより一般的に使用されているなら、Springはたぶんこのカテゴリでポイントを得るべきです。 しかし、証拠を提供するために時間をかけていないので、私は、Guiceに遠慮なくポイントを与えました。

(I'm sure that you're wondering where the numbers are that show Spring is faster in producing singletons. Unfortunately, the work done to produce these numbers is not mine and I am not sure if the author is ready to release his figures yet. If he's reading this, then he knows I'm talking about him here and I ask him to provide the numbers on his blog. When/if he does that, I'll put the link to his blog here.)


(数字上は、Springはシングルトンを生産するのが、より速いということを表しているということに驚いたと確信しています。 残念ながら、これらの数字を生産するために行われた仕事は私の担当ではありません、そして、私は作者がまだデータを発表していないことに関して、準備ができているかどうかを確信していません。これを読んでいるなら、彼は私がここで彼に関して話しているのを知っています。そして、私は彼のブログで数字を提供するように彼に頼んでいます。彼がそれをするなら、ここで彼のブログにリンクを張るつもりです。)

Again, let me repeat that I've had only a few days worth of experience with Guice as compared to a few years of experience with Spring. If there's a change that can be made to the Guice examples to make them better and to provide a more fair comparison, I'm eager to hear about it.


もう一度、繰り返して言わせていただきますが、数日のGuiceの経験で、Springの数年の経験と比べて同じぐらいの非常に価値のある経験をしました。より公正な比較ができるような、Guiceのサンプルにするためのアップデートがあることを、私は非常に待ち望んでいます。

Special thanks to Crazy Bob for his gracious offer to review my Guice example. He pointed out a few things about my example that could've been done a bit better. He also suggested moving the ".in(Scopes.SINGLETON)" part of the binding into the HolyGrailQuest and KnightOfTheRoundTable classes as a class-scoped @Singleton annotation. I chose not to do this, because it would be one more intrusion of Guice into my application objects. Finally, Bob wanted me to mention that Guice really shines when you use a dependency more than once (in the knight/quest example, the Quest dependency was only used once).


Crazy Bobに非常に感謝します。私のGuiceサンプルのレビューに親切なオファーをいただきました。彼は、私のサンプルをちょっとだけ良くするような、いくつかの指摘をくれました。彼は、また".in(Scopes.SINGLETON)"を移動するように提案してくれました。 また彼は、クラスを範囲とする@Singletonアノテーションとして、HolyGrailQuestとKnightOfTheRoundTableのクラスにバインディングの「.in(Scopes.SINGLETON)」の部分を動かすよう提案してくれました私のアプリケーションオブジェクトにGuiceがもう1つの部分で占拠してくることになるため、そうしませんでしたが。。最終的にBobは
私に、Guiceは一回以上の依存性を使用するとき、本当に光り輝くと言って欲しかったようです。(knight/questのサンプルでは、Questの依存性は一度使用されただけです)

Thanks also go to Rod Johnson, Colin Sampaleanu, and Costin Leau for going over the Spring JavaConfig bits and providing their feedback. Rod suggested that I mention that the @AspectJ advice style is way nicer than the AOP Alliance stuff (which is basically a legacy programming model in Spring 2.0). I fully agree that the @AspectJ stuff is pretty slick and I recommend it over the AOP Alliance stuff. I only used the AOP Alliance stuff here to provide a slightly more even playing field. (Although, in hindsight, an @AspectJ example would've been a slam-dunk in Spring's favor.)


また、Rod Johnson、 Colin Sampaleanu、およびCostin Leauに感謝します。Spring JavaConfigの具体例を調べて、それらのフィードバックを提供してくれました。ロッドは、私が@AspectJ アドバイススタイルがAOP AllianceでのAOP機能(基本的にSpring2.0のレガシープログラミングモデルである)よりずっと良いと述べてくれました。私は、@AspectJAOP機能は非常にすばらしいので、AOP AllianceのAOP機能ではなく、@AspectJを推薦するのに諸手を挙げて賛成です。私は、わずかに公平な遊び場を提供するのに、ここでAOP AllianceのAOP機能を使用しただけです。 (とはいえ、後から考えると@AspectJの例だったらSpring側に確実に有利だったでしょう。)

Finally, and before I get pointless comments to this effect: I realize that a "Knight's Tour" is a series of 64 moves by a knight piece on a chess board, where the knight visits every square once and only once. Had I given an actual "knight's tour" of Guice and Spring, my examples would've been more comprehensive (covering at least 64 points). I know the phrase isn't a perfect fit here, but it sounds cool, so I'm keeping it. :-)


結果として、以前、私は以下のような趣旨で無意味なコメントを得ました。
私は思い出しました。「Knight's Tour」はチェス盤の上のナイトの駒による64回の移動であり、ナイトはすべての場所に最低1回、最高1回だけ移動することができます。GuiceとSpringの実際の「Knight's Tour」を与えたなら、私の例では、より包括的でした(少なくとも64ポイントをカバーしています)。このフレーズがここでの完全にフィットしないことを知っていますが、それがクールに聞こえるので、このままにしときます。 :-)

And, in case you didn't catch those download links earlier, you can find the Guice example code here and the Spring JavaConfig example code here.


それから、万が一、これらのダウンロードリンクを簡単に見つけることができないときのために、Guiceのサンプルコードはここにあり、SpringJavaConfigのサンプルコードは、 ここにあります。