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
Thanks for the feedback.
First, the Guice manual uses “@Blue” not “@BlueService”. You typically have a small set of reusable annotations which you can share across multiple bindings; you don’t create a new annotation for each binding. It’s not like Spring where each name must be unique. Also, from my experience, you only use annotations about 5% of the time (if that); these aren’t equivalent to Spring’s bean names which you must always use.
Second, Spring actually spreads your configuration out more and requires more of it. With Spring, you have the configuration for Service, the XML mapping Service to Client, and Client itself–3 places. With Guice, you just have the configuration for Service and Client itself–two places.
I agree that there appears to be little benefit from using Guice in this small example (I point this out in the manual before we even start this example). The benefits from Guice kick in when you use Service again from another object. With Spring, you would need external XML to wire Service to each new object (autowiring is not an option). With Guice, you just put @Inject anywhere you need Service.
If maintainability is a high priority (we spend a lot more time reading code than we do writing it), then I would try Guice–that’s why we built it. For more information, check out our Guice/Spring comparison: http://code.google.com/p/google-guice/wiki/SpringComparison
I think he just wanted something else. When you’re working on a Spring project for months something completely different can be quite refreshing.
You started your blog with the remark that your old collegue is “tired of Spring”. It made me curious to read why….. Was your collegue just ready for a new challenge or did he mention an argument against this framework? I agree with your arguments that Guice DI does not offer any special benefits, as you described it.
While I was writing the blog entry yesterday I thought I saw something like the Guice config in Spring, but couldn’t find it on the Spring site.
Thanks for pointing me to that site, it looks promising and I totally forgot about it, but I have to read more about JavaConfig to see how it compares to Guice.
How would it look using the Spring Java annotation based configuration?
http://static.springframework.org/spring-javaconfig/docs/1.0-m2a/reference/html/