Guice Hello World

March 12, 2007

A new project called Guice (pronounced Juice, but starts with a G instead of J because it's Googlerrific) has been created. Guice aims to be a better Dependency Injection (DI) framework for Java. The de facto DI framework for Java is currently Spring. Spring provides a lot of things besides DI, but I think DI is it's main selling point. I often use Spring in projects only for it's DI. I use Stripes as my Web MVC framework and Hibernate as my ORM framework, so I don't need Spring's MVC layer or JDBC Template. I do use Spring's declarative transaction management and hibernate configuration features, but that's only because once you start using Spring for DI, it's easy to use those features as well, but they could be easily replaced.

The main disadvantage of Spring, in my opinion, is the amount of XML files that you have to create to configuration you application. The thing I dislike most about the XML configuration is that it is not type safe, and just like Bob Lee says:

I'm using a strongly typed language; why would I want to throw all of this perfectly good type information away? If I wanted that, I'd use Ruby.

I don't think he meant that statement as a knock against Ruby, he's just saying that if you are programming in Java, then you want to use type safety as much as possible. Annotations and Generics, features added to Java in Java 5, can allow you to do that, and Guice aims to provide dependency injection via Annotations rather than XML.

So I decided to take a look at Guice, and although the documentation is pretty good, it doesn't have a working "Hello World" type example to get you going, so I figured I would provide one here. I encourage you to play along at home.

First, download Guice, setup a new project in your favorite IDE, and add guice-1.0.jar to your classpath. What we're going to do is create a basic domain model object, Foo, and a DAO-like Manager for Foo, and then create a controller that depends on the FooManager, and has that dependency set using Guice. So here we go. Create the Foo class:

public class Foo {

    private Long id;
    private String name;

    //Generate and getters/setters in your IDE

}

Then create the interface for the FooManager:

public interface FooManager {

    public Foo get(Long id);
    public void save(Foo foo);

}    

Then create an implementation of the FooManager. In real life, you might implement this with an ORM framework like Hibernate, but this simple little thing serves the purpose for this example:

public class FooManagerImpl implements FooManager {

    private static Long fooSequence = 1l;
    private static final Map<Long, Foo> foos = new HashMap<Long, Foo>();

    public Foo get(Long id) {
        return foos.get(id);
    }

    public void save(Foo foo) {
        if(foo == null) return;
        if(foo.getId() == null) {
            foo.setId(fooSequence);
            fooSequence++;
        }
        foos.put(foo.getId(), foo);
    }
}

And for the last part of our app, we'll create a controller that calls our manager. This controller is sort of like what a controller in a web app might be like:

public class FooController {

    private FooManager fooManager;

    //----- Controller Actions -------------------------------------------------
    public Foo create(String name) {
        Foo foo = new Foo();
        foo.setName(name);
        fooManager.save(foo);
        return foo;
    }

    public Foo retrieve(Long id) {
        return fooManager.get(id);
    }

    //----- Getters/Setters ----------------------------------------------------
    public FooManager getFooManager() {
        return fooManager;
    }

    @Inject
    public void setFooManager(FooManager fooManager) {
        this.fooManager = fooManager;
    }

}

You can see that with the annotation Inject on the fooManager setter, we are asking Guice to inject a fooManager instance into our controller. Continuing with the web app like architecture of our app, we'll create a dispatcher. In a real app, this would be the FrontController responsible for directing the request to be handled by the appropriate controller action, but for our simple app, we'll just hard code 2 controller action methods to be called:

public class FooDispatcher {

    public static void main(String[] args) {

        FooController controller = new FooController();
        Injector injector = Guice.createInjector(new FooModule());
        injector.injectMembers(controller);

        //Our action is now injected with a FooManager, so let's use it
        Foo foo = controller.create("Bar");
        Foo bar = controller.retrieve(foo.getId());
        System.out.println("bar.name => "+bar.getName());

    }

}

As you can see here, we've now got some Guice specific code. First we create an injector using the FooModule. The FooModule is a class we create that serves as the configuration for Guice, we'll get to that in a minute. The creation of this injector is something that you would do once, probably upon application startup. Then, we ask the injector to inject our controller instance with its dependencies. The simple Inject annotation we added on the setFooManager method of our controller is all the info the injector needs to set up our controller. Next you see we call 2 action methods, one to create a new Foo instance, and then another to retrieve it.

So let's look at the FooModule, which is where we do our Guice configuration:

public class FooModule extends AbstractModule {

    protected void configure() {
        bind(FooManager.class)
            .to(FooManagerImpl.class)
            .in(Scopes.SINGLETON);
    }

}

What this says is that when something needs a FooManager injected into it, use a singleton instance of FooManagerImpl to fulfill that dependency. We can actually use annotations to further simplify this configuration. First, we add the ImplementedBy annotation to the FooManager interface:

@ImplementedBy(FooManagerImpl.class)
public interface FooManager {

    public Foo get(Long id);
    public void save(Foo foo);

}

This basically says to Guice that we want FooManagerImpl to be the default implementation class for FooManager. Also, we can specify that by default we want FooManagerImpl to be a singleton:

@Singleton
public class FooManagerImpl implements FooManager {

    private static Long fooSequence = 1l;
    private static final Map<Long, Foo> foos = new HashMap<Long, Foo>();

    public Foo get(Long id) {
        return foos.get(id);
    }

    public void save(Foo foo) {
        if(foo == null) return;
        if(foo.getId() == null) {
            foo.setId(fooSequence);
            fooSequence++;
        }
        foos.put(foo.getId(), foo);
    }
}

Now, we can modify our module to look like this:

public class FooModule extends AbstractModule {

    protected void configure() {
        bind(FooManager.class);
    }

}

An now when we re-run our FooDispatcher, every thing still works. In real life, there would be some core mechanism in the web app framework to handle creating the injector and injecting dependencies into the controller instances, and I'm sure it would be fairly trivial to implement that into Stripes.

Although some people don't think Guice is going to replace Spring, I think for projects where Spring is being used mostly for DI, we will see Guice or something like it start to replace Spring. I also predict that in response to this, Spring will be forced into incorporating an annotation-based configuration mechanism into its core codebase in order to remain popular in the oncoming wave of Annotation based "zero" configuration frameworks like Stripes, Struts 2 and Hibernate.

UPDATE: Monday, March 12, 5:18pm

Thanks to a tip from Bob, I've discovered that once you have every thing configured by annotations, as we do at the end of this example, you can completely remove the FooModule, which gives you the code like this in the dispatcher:

public class FooDispatcher {

    public static void main(String[] args) {

        FooController controller = new FooController();
        Injector injector = Guice.createInjector();
        injector.injectMembers(controller);

        //Our action is now injected with a FooManager, so let's use it
        Foo foo = controller.create("Bar");
        Foo bar = controller.retrieve(foo.getId());
        System.out.println("bar.name => "+bar.getName());

    }

}

The point is that for any class that you can configure with annotations, you don't need to explicitly define them in a module, or anywhere. So take an app with 50 different manager classes, all you would have to do is create a manager interface, annotate it as a singleton, and then create the default implementation. Compare that with a minimum of 50 bean entries in a Spring context configuration XML file, and you can see how Guice can really start to simplify your configuration.

Posted in Technology | Tags Spring, Hibernate, Stripes, Java, DependencyInjection, Guice | 28 Comments

PaulBarry.com 3.0

January 28, 2007

So I've finally finished the latest version of my site. The first version of my site went online on March 3rd of 2006 using WordPress. Then on my last birthday, I switched to Typo. Now, I've got up the first version of my site that I have built myself, using Java, Stripes, Spring and Hibernate. I'm using Resin as the Web/Application server and MySQL for the database. The OS is Ubuntu and it is hosted with VPSLand.

I hoping that this version will be more stable than the previous version. If you are having any problems using the site, let me know.

Posted in Technology | Tags Resin, Spring, Hibernate, Stripes, MySQL, Java, Ubuntu | 6 Comments

Struts is still on top

March 10, 2006

According to poll conducted by JBoss, Struts is still the number one web framework, and by a convincing margin at 59%. Second place is Java Server Faces at 35% and Spring MVC is at 26%. I'm surprised to see WebWork so low down at 5%. There seems to be a lot of discussion about WebWork, I would have thought it would be higher than Spring MVC. I thought no one uses Spring MVC. And I am also surprised to see Struts so high. I would have thought most people would have moved on from Struts by now.

My personal experience with MVC frameworks is pretty simple. I first start to learn the MVC pattern with Struts, which I think many other people did because it was the first mature MVC product to gain significant mindshare. Struts had some limitations, but was certainly better than building your own web framework. I developed a couple of apps using Struts, happily creating ActionForms and using a mix of the struts tags and JSTL (it was in 1.1 in those days) in my views.

Then I discovered Spring, which was more appealing simply from the standpoint that it addresses the whole stack of your application, not just the web part. When I first started using Spring, I stuck with Struts for the web framework, partially because the Spring MVC framework seemed confusing at first. But the more I studied the Spring MVC framework, I started to like the Data Binder and the way it treats GET versus POST requests. Also, the ability to easily plug in a different view layer technology, such as velocity, which seemed infinately cleaner than JSP to me, made me switch to Spring MVC.

At this point, I haven't felt compelled to actually bother evaluating any of the other frameworks. Spring seems at least "good enough" at this point. WebWork, JSF, Tapestry, Wicket, maybe some of these frameworks have features that make them better. But it takes time to get up to speed on new frameworks, and it doesn't seem like it would be worth the time for me to invest in it at this point.

And maybe that's exactly why Struts is still on top. If you don't take the time to really evaluate what else is out there, you'll always think what you are using is good enough. Well my personal experience has been that Spring MVC has made me a more productive developer. So if you haven't do so yet, check out another framework, because it can make you a better developer too. And I'll make a pledge to myself to check out a few of the other web frameworks as well.

Posted in Technology | Tags Struts, Spring, Java, WebWork | 0 Comments

Spring Web Services Framework

February 13, 2006

Spring Web Service 0.9 was released today. Sounds like it is going to work similar to many of the other features we are already used to using with Spring. As I am probably going to be working with web services a lot in the near future, I'm definately going to give this a try. I'll let you know what I think.

Posted in Technology | Tags Spring, Java | 0 Comments