Nov 02

Guice Impressions from a Spring Veteran

Tag: guice, hibernate, java, spring, wicketpmularien @ 9:28 pm

I decided to do a quick investigation of Google’s Guice dependency injection framework. The impetus for this was the recent excitement on TheServerSide regarding Guice vs. Spring, and the ensuing (and always entertaining) TSS discussion thread.

Being a long-time (4+ years) Spring user myself, I decided to download Guice, read through the docs, and have a go at it. I hope this perspective as a long-time Spring user is useful if you’re considering looking at Guice (I admit that Guice has been available for some time, and I’ve just now gotten around to trying to code with it). Craig Walls has an excellent writeup on Guice vs Spring along with a good, detailed example, done in March 2007.

Background

I’ll try to keep this entry at a relatively high level, directed at people who might be considering Guice and where it fits in an application stack vis-a-vis Spring.
Since I’ve recently developed a couple good applications with Spring, I decided a first crack at learning Guice would be to see how I would apply it the simpler of the two projects, and replace our use of Spring 2 with Guice instead. The application in question is a pretty standard Web-based application, using Wicket 1.2, Spring 2, and Hibernate 3.

Guice in a Nutshell

I have to say that the quality of the documentation for Guice is excellent. Bob Lee and the Guice team have done a great job providing a well-written and concise user guide which covers the breadth of Guice through some good examples. Additionally (happily) the Guice crew apparently actually understands how to write quality Javadoc! Take a look at the Javadoc for Binder (one of the key concepts in Guice) for an exquisite example of code documentation. Nice to see in an open-source project!

I was able to come up with some simple examples where I could wire interfaces and implementations together with annotations, without annotations, and perform simple binding of configuration parameters. These were straightforward and intuitive, and the use of method chaining along with the binder DSL made for some very readable, Ruby-esque code.

Guice is definitely a very elegant way of building an application using good DI principles. I tried very hard to suspend my prior bias towards Spring-style XML configuration, which can get very hairy if you have a project with hundreds or thousands of beans spread across multiple XML files.

I could see Guice working very well in a strictly component-based environment where code is widely shared across applications, with very loose coupling and good attention to API contracts — someplace like Google, for instance.

Guice and the “Real World”

Therein lies the problem, however. I am an application developer by trade, and those applications have generally been web-based, and involve the typical 3 tiers - web, business, and data. Guice shines at the business tier, but quite literally has almost nothing to address the inherent complexities of managing dependencies across tiers.

Guice provides very short shrift to the web tier, giving a modicum of session- and request-scoped bindings, with (shockingly!) almost no formal documentation. No examples exist on the Guice site to provide the newbie with any clue how to tie it into a real-world application. Guice relies on “viral” dependency injection - in order to get a Guice-injected resource, you need access to the actual Injector object. The common suggestion for this is to stuff this reference in a static or ThreadLocal. Unfortunately, Guice doesn’t inherently provide you with a canned way to do this - it’s left as an exercise to the reader.

The “exercise to the reader” issue is one you’ll run across often, and I think is a testament to the laser focus of the Guice framework. Guice is really intended to be (only?) a great dependency injection and management framework, but it needs a lot of integration with other bits in your stack to make it work.

In my test case (Wicket / Spring / Hibernate-based application), I had some amount of success.

Wicket 1.3 beta 4 offers built-in support for Guice injections into components, and after going through the well-documented Wicket 1.2 to 1.3 upgrade pain, it “just worked” as easily as the Wicket - Spring integration does. This is a result of Alastair’s stellar work on the Wicket project - great job!

Unfortunately, the data tier proved to be more problematic. Although there are various suggestions about design patterns on the Guice newgroups, including copious feedback from Bob and the Guice team, there’s not yet a good choice for integrating Guice with your data tier (ORM or JDBC layer). A project that looks promising is the warp-persist module from Dhanji Prasana, which integrates Guice and annotations around a transactional framework that can itself wrap Hibernate or JPA. I plan on evaluating this very soon, although at this point it is in heavy development, and as such suitable only for development environments. One of the reason that I am excited about the warp-persist project is that the (only?) author, Dhanji, is very active on the Guice newgroups, as well as providing some excellent Warp-related articles on his blog.

So, if you were to try to build a web application stack with Guice, it might look like this:

  • Web Tier: Wicket
  • Business Tier: Guice / Warp-persist
  • Data Tier: JPA

This certainly seems reasonable, and I bet around the time that Warp gets more stable, and Guice 1.1 (or 2.0?) is released, I’ll start getting good questions from folks who want to use it.

… and Spring

Contrast the discussion of the previous section with Spring, which has great appeal to architects and business types, because it takes the “kitchen sink” approach and literally can manage your whole top two tiers (web and business/service), down through transaction management and into the data tier. For architects or technical designers, Spring is still a pretty safe bet to build an application stack with, simply because it does almost everything you need already.

Trying to convert an existing application which uses broad features of Spring into an application based solely on Guice is basically nonsensical - if you’ve invested a lot in the breadth of Spring, you’re going to be very disappointed in the lack of breadth available in Guice.

Even simple things that Spring does, such as externalizing property bindings into properties files (a must for applications that are configured per environment, or per customer), are roll-your-own in Guice. Although Guice may be a more elegant way to tie dependencies together, you’ll find that it requires a lot of hard thinking on how to “do the right thing,” a task which many pragmatic developers will have a hard time with.

Which should you use?

As with many other things, the right tool for the right job. I could see Guice being ideal for non-web based applications, and generally promoting good design principles. It is extremely lightweight, and as such could be used in client-side apps launched via Java Web Start. Definitely worth paying attention to as it, and the community around it, develops.

(The curious reader may wonder why I haven’t touched the XML-vs-java configuration argument. I will explore that in a later article when I have time to review the changes and enhancements in Spring 2.5, nee Spring 2.1!)

Thanks for reading!

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>