Hello Guice!

August 22, 2009

For my first venture into Guice territory, I wanted to create an absurdly simple web application that both works and demonstrates an aspect of the dependency injection capabilities of Guice. The result is a single-servlet web application which uses a Guice Module to retrieve an implementation of an interface for use within a Servlet.

The interface and implementation, called Greeter and DefaultGreeter, define and realize a simple function called getGreeting() which returns the obligatory "Hello World!".

package com.earldouglas.simpleguice;

public interface Greeter {

    public String getGreeting();
}
package com.earldouglas.simpleguice;

public class DefaultGreeter implements Greeter {

    public String getGreeting() {
        return "Hello World!";
    }
}

The Guice Module, an analog to a Spring context configuration, simply binds the Greeter interface to the only implementation of DefaultGreeter.

package com.earldouglas.simpleguice;

import com.google.inject.AbstractModule;

public class SimpleGuiceModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Greeter.class).to(DefaultGreeter.class);
    }
}

Because I have been tempered in annotations, it feels odd not to need @Inject nor @ImplementedBy, etc. This is because with Guice annotations are only needed when more than simply a binding type is required.

All that's left is to create a Guice Injector with SimpleGuiceModule, retrieve an instance of a Greeter, and do something with the greeting. In this case, the greeting is simply written to the response in a Servlet.service() method.

package com.earldouglas.simpleguice.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;

import com.google.inject.Guice;
import com.google.inject.Injector;

@SuppressWarnings("serial")
public class SimpleGuiceServlet extends HttpServlet {

    @Override
    public void service(ServletRequest servletRequest,
            ServletResponse servletResponse) throws ServletException,
            IOException {

        Injector injector = Guice.createInjector(new SimpleGuiceModule());
        Greeter greeter = injector.getInstance(Greeter.class);

        servletResponse.setContentType("text/html");
        servletResponse.getWriter().write(greeter.getGreeting());
    }
}

My means of bootstrapping my application are certainly suboptimal for anything more complicated than this single-servlet example, however for this simple case it seems to work well enough.

SimpleGuiceServlet is added to the web application in the standard way.

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>simpleguice</display-name>

    <servlet>
        <display-name>Simple Guice</display-name>
        <servlet-name>simpleguice</servlet-name>
        <servlet-class>com.earldouglas.simpleguice.web.SimpleGuiceServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>simpleguice</servlet-name>
        <url-pattern>/greeter</url-pattern>
    </servlet-mapping>

</web-app>