Google Guice, First Look
Monday, October 6, 2008 at 5:21PM This is the first in a series of articles on Google Guice. I've been working with Chariot Architect Lyle Anderson, who has done a lot of research on wiring together an application using this Inversion of Control framework.
Overview
Guice is an annotation-driven IoC framework, meaning that, once bootstrapped, Guice will inject classes based on annotated code, rather than XML files. There are advantages and disadvantages to each approach, so I'm not espousing either one, but if you're into XML-driven configuration, you should probably look at Spring or another XML-based platform.
A simple Maven build
To start building Guice, you need to construct a build file. I use Maven for much of my development, so I started with a very thin build file. An excerpt of the maven build file:
<project ...><modelVersion>4.0.0</modelVersion>
<groupId>com.rimple.guice.demo</groupId>
<artifactId>simpleguiceapp</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>guicewebapp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<artifactId>guice</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Now, placing a simple file in src/main/com/rimple/guice/GuiceRunner.java, we can run the application under Maven using the exec:java goal:
mvn -e exec:java -Dexec.mainClass=com.rimple.guice.GuiceRunner
Now we have a simple test bed in which to place our test Guice application.
A Simple Guice configuration
Guice is bootstrapped by building an Injector. The Injector exposes a method, getInstance(Class) that is used to pull an initial bean out of the context. It is configured using the Guice.createInjector() method, which takes several parameters:
- A Stage enum, which is either DEVELOPMENT or PRODUCTION. DEVELOPMENT provides quick startup, but will incur more overhead at runtime and log more details to the error logging system. PRODUCTION takes longer to load but performs diagnostic checks at startup in order to speed runtime performance.
- A varargs list of Modules, which are units of configuration. Each module has its' own configuration which is defined using a Guice DSL defined in the configure() method. A sample configuraiton, from Lyle's calculator:
public class CalculatorModule extends AbstractModule {
@Override
protected void configure() {
bind(Calculator.class)
.to(CalculatorImpl.class)
.in(Scopes.SINGLETON);bind(PrintService.class)
.to(PrintServiceImpl.class)
.in(Scopes.SINGLETON);bind(MemoryService.class)
.to(MemoryServiceImpl.class)
.in(Scopes.SINGLETON);bind(CalculatorOperationDAO.class)
.to(HbmCalculatorOperationDAO.class)
.in(Scopes.SINGLETON);... etc..
So, to configure the Injector to include a CalculatorModule, you may bind it this way:
Injector injector = Guice.createInjector(Stage.PRODUCTION, new CalculatorModule());To use a class configured within the injector, such as the PrintService, you need to call the injector's getInstance() method. From there, any annotated classes defined in the Injector will be wired in automatically. For example:
PrintService printService = (PrintService) injector.getInstance(PrintService.class);Next Steps
In part two, we'll cover the annotations themselves, and how they are used by the injector.
Guice,
IoC,
Tutorial in
Guice,
Technologies 


Reader Comments