A quick look at Guice A dependency injection framework by Google html

A quick look at Guice A dependency injection framework by Google

About a month ago I read an entry on Dion Almaer’s blog about Google Guice. On the blog is a link to a video of a google tech talk about guice. I finally watched the video today. A few days before that blog entry an old colleague of mine told me he was tired of Spring and wanted to take a look at Guice. He also told me about jQuery a while ago and that was pretty cool, so maybe he is right again.

Guice is a dependency injection framework and does some AOP stuff (which isn’t handled in the video). The video takes about an hour and handles the basic concepts of Guice. It’s convenient when you know something about dependency injection because it isn’t explained in great detail (which is a good thing when you only have one hour). My main goal of watching the video was to see whether this was an alternative to Spring. I have absolutely no complaints about Spring, but sometimes the grass is greener on the other side.

Injecting with annoations

The developers of Guice don’t like to configure things in XML. They developed a DI framework where you configure everything with annotations.
Let’s say you have a class called Service and want to inject this class into your code. It would look like this (note that all code examples are copied from the Guice manual):

public class Client {

 private final Service service;


  @Inject
  public Client(Service service) {
    this.service = service;
  }
  
  public void go() {
    service.go();
  }
}

Guice automatically finds the Service class and injects it into your Client class. That’s pretty cool at first sight. But here’s the catch. You usually progam to interfaces. That’s also possible with Guice, but when you have more than one implementation of your interface it’s going to look weird.

First let’s take a look at the situation when there’s only one implementation:

bind(Service.class).to(ServiceImpl.class);

(this code is entered in a class that handles the configuration)

That looks pretty compact and still very understandable. But when there are two implementations we have to create two annotation files. Assume we have two implementations of the Service interface, called RedService and BlueService.

To inject the Blue implementation to the service we have to add a @BlueService annotation:

@Inject @BlueService Service service;

We have to define this @BlueService in a separate file and bind the @BlueService annotation to the injector:

bind(Service.class)
.annotatedWith(BlueService.class)
.to(BlueService.class);

The BlueService annotation file:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface BlueService {}

The same goes for the RedService implementation. I think this is too much work and you end up with a BlueService.java and RedService.java file that are not really needed.

When we use Spring it would’ve looked like this:

<bean id="client" class="com.google.Client">
  <property name="service">
    <ref bean="service"/>
  </property>
</bean>

<bean id="service" class="com.google.BlueService"/>

My personal opinion is that this is much clearer and the information is in one place instead of 2 (or actually 3 when you count RedService). Ok, it’s XML, but to work around that by creating an extra file is too much hassle for me. One good point might be that it’s very easy to rename BlueService to DarkBlueService, renaming this in XML might lead to errors (but probably your IDE can help a great deal with this)

Another bad thing about using annoations is that your Client class now depends on Guice. When you use setter injection and program to interfaces (with Spring for example) you don’t know which framework is used, which is a good thing.

Conclusion

The video was fun to watch. Of course Guice is a direct competitor of Spring, but the google guys didn’t talk about Spring, they just told why Guice is good and didn’t bashed the Spring guys. I can’t agree with all the arguments they gave me. Typo’s for example. Because everything is in the code it’s much less likely that you make typo. But my argument against that it that if your application breaks because of a typo your unit test probably isn’t right. The first time I made a typo in Spring I was a bit confused, but now I learned to recognize them and of course the unit test will also discover it. And nowadays with IntelliJ IDEA and the Spring IDE plugin for Eclipse most typo’s are discovered before you start compiling your classes.
There was also a short part about what’s bad about the Factory and Service Locator pattern, also very interesting to watch.
The part of the unit testing I didn’t really get. I think you can unit test this way with every DI framework, or maybe I just missed something out here. And what’s bad about extending from the AbstractDependencyInjectionSpringContextTests, it’s not very likely that you start switching a DI framework. A DI framework is the foundation of an application, changing that is like moving walls in your house, it’s possible but probably too expensive.

For now I’ll stick with Spring, but Guice might be worth a shot when you can decide which framework to use. But I can’t see any big advantages. Spring is widely spread, there are many books about Spring and a lot of developers have experience with Spring.

But the video isn’t a waste of time, even when you don’t plan to use Guice. It’s good to know what frameworks are around and you’ll learn some other things too.

Sources

Guice home page
Blog entry of Dion Almaer
Guice User’s guide
Google’s comparison to Spring

5 Comments

  1. Bob Lee May 26, 2007
  2. Jeroen van Wilgenburg May 21, 2007
  3. erik May 21, 2007
  4. Jeroen van Wilgenburg May 21, 2007
  5. Mikael Gueck May 21, 2007