Guice vs. SpringJavaConfig (1) A Knight's tour of Guice

Guice vs. Spring JavaConfig: A comparison of DI styles

DIスタイルの比較:Guice 対 SpringのJavaコードコンフィグ


With all of the excitement surrounding Guice lately, I thought it might be worthwhile to compare Guice with Spring JavaConfig. Both represent different approaches to annotation-based dependency-injection. I've chosen to reimplement my knight/quest example from chapter 1 of Spring in Action to illustrate the basics of each option.

この記事ではそれぞれの基本的な機能を説明するために「Spring In Action」のチャプター1から「 knight/quest 」サンプルを再実装することにします。

Before I get started, a few disclaimers:

  • As the author of Spring in Action, it should be no surprise to you that I will have a difficult time being unbiased. Therefore, I will make no pretense of impartiality. However, I will do my best to be as fair as I can be to both Guice and Spring JavaConfig.
  • As someone who has several years of Spring experience to match his few days of Guice experience, I will admit that my knowledge of Guice isn't up to par with my knowledge of Spring. Therefore, it is quite possible that there are things about Guice that I simply do not know about and have not taken advantage of in my comparison. I assure you that failure to use the best possible Guice technique is not meant to devalue Guice, but merely due to the fact that I'm not as experienced as Guice as I am with Spring. For what it's worth, while I have several years of Spring experience, I'm still relatively new to Spring JavaConfig.
  • This is only a comparison of Guice with Spring JavaConfig, the core Spring container, and (to a lesser degree) Spring AOP; it is not a comparison of Guice to the entire Spring Framework.The Spring Framework is much more than just its core dependency injection container, providing functionality that Guice does not provide or claim to provide.
  • My comparisons will with Guice 1.0, Spring JavaConfig 1.0-m1, and Spring 2.0.2.

With that out of the way, let's get started. Since Spring is the hometeam in this matchup, I'll let Guice take the field first.


  • 「Spring in Action」の著者である著者が、公平になることはなかなか難しいということをご理解ください。そのため私は公平なフリをするつもりはありません。しかしながら、GuiceとSpring JavaCondfigの両方に対して、できるだけ公平であるように勤めます。
  • Springが数年の実績を持っているのに対して、Guiceはたかだか数日の実績しかありません。私のGuiceの知識はSpringに対する知識には遠く及びません。そのため 私がGuiceに関して知らないために比較で利用できないものがあることは非常にありえます。私にGuiceのテクニックを最大限つかえはしないということを断言できます。しかしそれは、Guiceの価値が下がると言うことを意味してはいません。ただ単に私がSpringほどにはGuiceを使ったことがないと言うだけの問題です。これはあくまでも私の意見ですが、数年Springを経験してきましたが、私はまだSpring JavaConfigに比較的経験が少ないほうです。
  • この記事は単なるGuiceとSpringのコアコンテナと(より少ない度合いで)Spring AOPに対するSpring JavaConfigの比較です。GuiceとすべてのSpring Frameworkの比較ではありません。Spring FrameWorkは、コアであるDIコンテナだけではなく、Guiceが提供または要求していない、より多くの機能を提供するものです。
  • 私の比較は、Guice1.0とSpring JavaConfig 1.0-m1およびSpring 2.0.2によるものです。

そんなところで、はじめていきましょう。 Springがこの比較の「地元チーム」なので、まずはGuiceからグラウンドに出して行きましょう。

A Knight's tour of Guice Gucieにおける騎士ツアー

In Guice, much of the configuration is done in the context of a module class. This class effectively binds classes to interfaces within the Guice injector, so that Guice knows how to resolve certain dependencies. Here's what the KnightModule class that I wrote looks like:


package com.springinaction.chapter01.knight;
import static com.google.inject.matcher.Matchers.annotatedWith;
import static com.google.inject.matcher.Matchers.any;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Scopes;

public class KnightModule extends AbstractModule {
  public void configure() {

      new MinstrelInterceptor()
  public static void main(String[] args) throws Exception {
    Injector injector = Guice.createInjector(new KnightModule() );
    Knight knight = injector.getInstance(Knight.class);

(Note that for space considerations I'm only going to show the code that is pertinent to the comparison of Guice with Spring JavaConfig. The full source code for the Guice examples will be available here, while you'll be able to find the Spring JavaConfig examples here. Also notice that I've placed the main() method in KnightModule for convenience only--you may or may not want to do this in a real-world application.)

(スペースへの配慮のために、GuiceとSpring JavaConfigの比較に必要なコードだけを表示しますので注意してください。Guiceのサンプルのすべてのソースコードは、ここで入手できます。また、実際のアプリケーションではそんなことはやらないかもしれませんが、便利であるというためだけにKnightModukeの中にmain()メソッドを置いてることにも注意してください。)

The first thing you'll see is the configure() method. This method, which is mandated by the AbstractModule class, is used for, among other things, binding interfaces to an implementation classes. This is important, because in Guice, you do not explicitly wire objects together--instead you declare that a property, constructor argument, or even a method argument needs to be injected and Guice will automatically (or semi-automatically, to be more accurate) find an implementation to match the property or argument.


For example, notice that the Knight interface is bound to the KnightOfTheRoundTable class. What this is basically telling Guice is that anytime it needs to inject a property or argument that is of type Knight, it should use the concrete KnightOfTheRoundTable implementation. Similarly, the Quest interface is bound to the HolyGrailQuest class. Thus when KnightOfTheRoundTable needs its quest property wired with a Quest implementation, Guice will oblige with a HolyGrailQuest.

たとえば、Kightインターフェイスは、KnightOfTheRoundTable クラスにバインドされています。これは基本的に、GuiceはいつでもKight型のプロパティーや引数にインジェクトするひつようがあるということを意味しています。具体的なKnightOfTheRoundTable実装を使うべきです。同じようにQuestインターフェイスは、HolyGrailQuestクラスがバインドされています。

Along with being wired with a Quest implementation, the KnightOfTheRoundTable class is also constructed with a String value that is the knight's name. Unfortunately, I could find no more straightforward way of wiring a String value into KnightOfTheRoundTable's constructor without binding the value through an annotation. Thus, the call to bindConstant() tells Guice to inject the value "Bedivere" into any String that is annotated with @Name (which is a custom annotation that I created as an "anchor" to bind the String injection to).


In the case of both the Quest and Knight bindings, the in() method is called to set the scoping of the bean to be singleton. Optionally, you can leave this out and instead place a @Singleton annotation on the KnightOfTheRoundTable and HolyGrailQuest classes. However, for reasons I'll describe later in this article, I don't particularly recommend the @Singleton annotation.


I'll come back to the call to bindInterceptor() in a moment. But first, it's important to know that KnightModule only tells Guice about the objects and values that it is to inject. It doesn't say where to inject them. For that, I had to place annotations in the KnightOfTheRoundTable class. Here's the modified KnightOfTheRoundTable.java:

ここでは、それらをインジェクトするためにとは言いません。という理由で、KnightOfTheRoundTable クラスにアノテーションを置く必要があります。ここでは、KnightOfTheRoundTable.javaファイルを書き換えます。

package com.springinaction.chapter01.knight;

import com.google.inject.Inject;

public class KnightOfTheRoundTable implements Knight {
  private String name;
  private Quest quest;
  public KnightOfTheRoundTable(<b>@Name</b> String name) {
    this.name = name;
  public Object embarkOnQuest() throws QuestFailedException {
    return quest.embark();
  public void setQuest(Quest quest) {
    this.quest = quest;
  public String getName() {
    return name;

Notice the use of the @Inject annotation on both the constructor and the setQuest() method. This annotation tells Guice that it needs to inject some values into the arguments of the constructor and method that it annotates. Without this annotation in place, Guice will pass over those methods and not perform any injection at all.


First look at the setQuest() method. It is annotated with @Inject and has a Quest argument. As you'll recall, Quest is bound to HolyGrailQuest. Therefore, when Guice is configuring the KnightOfTheRoundTable object, it will call setQuest(), passing in a reference to a HolyGrailQuest object.

初めに見るのは、setQuest()メソッドです。これは@Injectでアノテートされていて、Quest型の引数を持っています。思い出してください、QuestはHolyGrailQuestにバインドされています。そのため、GuiceがKnightOfTheRoundTable オブジェクトを設定したときには、setQuest()メソッドが呼び出され、HolyGrailQuestオブジェクトの参照が渡されます。

It should also be noted that although this example doesn't show it, Guice can also inject into any method, not just setters and constructors. So, even if the setQuest() method were renamed to giveMeAQuestPlease(), Guice would still call it, passing in a HolyGrailQuest object.


Also, instead of explicitly binding Quest to HolyGrailQuest in KnightModule.java, I could've used the @ImplementedBy annotation in Quest.java to bind HolyGrailQuest to Quest. For example, here's the Quest interface, annotated with @ImplementedBy:


package com.springinaction.chapter01.knight;
import com.google.inject.ImplementedBy;

public interface Quest {
  public Object embark() throws QuestFailedException;

The @ImplementedBy annotation is effectively equivalent to the bind() call I used in KnightModule. The difference is that it sets up Quest to be bound to a default implementation class, should one not be bound to Quest in KnightModule.


Now look at the constructor. It is also annotated with @Inject. And it has a String argument that is annotated with @Name. The @Inject argument tells Guice that the constructor must be injected, while the @Name annotation (a custom annotation that I created to help this example along) helps Guice know what to inject it with. Back in the KnightModule class, we bound the String value "Bedivere" to the @Name annotation. Therefore, when KnightOfTheRoundTable is constructed, it will be constructed with the argument being set to "Bedivere".