My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
GettingStarted  
How to start doing dependency injection with Guice.
Updated Oct 16, 2011 by sberlin

Getting Started

With dependency injection, objects accept dependencies in their constructors. To construct an object, you first build its dependencies. But to build each dependency, you need its dependencies, and so on. So when you build an object, you really need to build an object graph.

Building object graphs by hand is labour intensive, error prone, and makes testing difficult. Instead, Guice can build the object graph for you. But first, Guice needs to be configured to build the graph exactly as you want it.

To illustrate, we'll start the RealBillingService class that accepts its dependent interfaces CreditCardProcessor and TransactionLog in its constructor. To make it explicit that the RealBillingService constructor is invoked by Guice, we add the @Inject annotation:

class RealBillingService implements BillingService {
  private final CreditCardProcessor processor;
  private final TransactionLog transactionLog;

  @Inject
  RealBillingService(CreditCardProcessor processor, 
      TransactionLog transactionLog) {
    this.processor = processor;
    this.transactionLog = transactionLog;
  }

  @Override
  public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
    ...
  }
}

We want to build a RealBillingService using PaypalCreditCardProcessor and DatabaseTransactionLog. Guice uses bindings to map types to their implementations. A module is a collection of bindings specified using fluent, English-like method calls:

public class BillingModule extends AbstractModule {
  @Override 
  protected void configure() {

     /*
      * This tells Guice that whenever it sees a dependency on a TransactionLog,
      * it should satisfy the dependency using a DatabaseTransactionLog.
      */
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);

     /*
      * Similarly, this binding tells Guice that when CreditCardProcessor is used in
      * a dependency, that should be satisfied with a PaypalCreditCardProcessor.
      */
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
  }
}

The modules are the building blocks of an injector, which is Guice's object-graph builder. First we create the injector, and then we can use that to build the RealBillingService:

 public static void main(String[] args) {
    /*
     * Guice.createInjector() takes your Modules, and returns a new Injector
     * instance. Most applications will call this method exactly once, in their
     * main() method.
     */
    Injector injector = Guice.createInjector(new BillingModule());

    /*
     * Now that we've got the injector, we can build objects.
     */
    RealBillingService billingService = injector.getInstance(RealBillingService.class);
    ...
  }

By building the billingService, we've constructed a small object graph using Guice. The graph contains the billing service and its dependent credit card processor and transaction log.

Comment by georg.oettl, Apr 22, 2009

I remember that a short time ago the call "injector.getInstance(RealBillingService?.class);" was regarded as an evil thing to do. `the advice was to use a provider instead. Isn't this valid any more?

Comment by project member limpbiz...@gmail.com, Jul 30, 2009

Calling Injector.getInstance() is a perfectly reasonable thing to do when you're bootstrapping your application. What's discouraged is injecting the injector everywhere, because it degrades to the service locator pattern.

Comment by alexnosp...@gmail.com, Aug 17, 2009

Where are the declarations for TransactionLog? and the other classes? I just don't get it. All of this code would just throw class not found exception. Please document this better.

Comment by lugieb...@gmail.com, Sep 6, 2009

It would help out a lot if you mentioned in the documentation somewhere that to get the injector all one needs to do is

@Inject
Injector injector;

It took me the better part of the last hour to figure that out.

Comment by adnem2...@gmail.com, Dec 10, 2009

I am not sure I understand the need for this code:

@Inject Injector injector;

It seems to me that this is field injection to inject the Injector's dependencies ? I would think the injector would be bootstrapped and provided as a static reference for the entire application. So only one instance containing all the configuration is initialized once and broadcasted by one single static helper. I was also doing some testing and noticed that when I omitted the @Inject on the RealBillingService?, my client code worked just fine when I ran the Junit. I thought that it wouldn't be able to find the dependencies of the constructor's args but it looks like that it did. That confuses me. Note that however, I put the TransactionLog?, CreditCardProcessor? interfaces and their implementations in the same package and JAR as the RealBillingService? client. Could this be why Guice is able to find the proper constructor's args dependencies without the @Inject ?

Comment by ljh552@gmail.com, Dec 22, 2009
I am not sure I understand the need for this code:

@Inject Injector injector;

It seems to me that this is field injection to inject the Injector's dependencies ? I would think the injector would be bootstrapped and provided as a static reference for the entire application. So only one instance containing all the configuration is initialized once and broadcasted by one single static helper. I was also doing some testing and noticed that when I omitted the @Inject on the RealBillingService??????, my client code worked just fine when I ran the Junit. I thought that it wouldn't be able to find the dependencies of the constructor's args but it looks like that it did. That confuses me. Note that however, I put the TransactionLog??????, CreditCardProcessor?????? interfaces and their implementations in the same package and JAR as the RealBillingService?????? client. Could this be why Guice is able to find the proper constructor's args dependencies without the @Inject ?

Why I cannot, If I don't have the @Inject The system will throw exception and tell me cannot find the proper constructor.

PS: I tested that only the constructor without the parameters and you declared obviously in the class will not need the annotation @Inject. This is the default constructor that GUICE invoke.

PS2: my all the class is in the same package too!

Comment by steven.h...@gmail.com, Jan 9, 2010

From what I've read, Spring usually has an xml file to specify the object graph for the dependency injection, which would allow someone to change the object graph without recompiling the application.

The Guice example shown above would mean that a change to the object graph would require a recompile / redeployment. Is this correct?

Comment by Hannes.J...@gmail.com, Jan 16, 2010

Guice is actually about modularization and configuration. Dependency Injection is also possible without it, as mentioned in the video.

Comment by hob...@gmail.com, Aug 16, 2010

I have spent days looking at guice wiki and the many posts of people with problems (e.g. when the singleton is not a singleton, or how to manually avoid creating multiple injectors etc. What about this one? http://markmail.org/message/eb6osvv5cbk4g6zr this would frighten off most people).

I still dont get it. I cant look at a guice example and guess whats actually happening.

The factory and singleton pattern are so simple, and so easy to understand/use/debug, I just cant see the compulsion to use a "magic" framework which makes understanding exactly whats going on very difficult, and code hard to debug. Explicit simplicity over implicit complexity any day, even if I have to write some extra lines of easy to follow code.

Is rigidly defined modularity, e.g. using Guice injection for everything, worth the cost of learning/using/debugging a new framework into your code, rather than just making your software modular by design with out it? The complexity increase certainly isnt worth saving some lines of code.

This reminds me of EJB again - eveyone was doing it (including us), then when we relised it made our code slower/harder to write and maintain, the whole thing was dropped.

Or is it just me?

Comment by kwhittin...@gmail.com, Nov 22, 2010

This relates to the first comment. In a stateless web app what's the best way to use Guice? Is calling injector.getInstance(MyRequestHandler?.class) each time the right pattern? What would be really nice is an Implementation patterns page on the wiki. That would save a lot of time parsing the Guice Groups page for answers

Comment by verydap...@gmail.com, Jan 18, 2011

is there an alternative to spring's <component-scan />??

Comment by simone.t...@gmail.com, Jan 18, 2011

@verydap... not in the Guice core itself, but take a look at the Guice Automatic Injection project (https://github.com/manzke/guice-automatic-injection/) by Daniel Manzke.

Comment by josh.all...@gmail.com, Apr 20, 2011

Hi, this looks like a cool way of doing IoC. Where is the best place to put the Injector in a web app, like Spring MVC on Apache? And now we have a global Injector object that we always use instead of using the new operator? What's the best way to give access to the Injector throughout the app?

What have people found about how best to structure your configuration modules? I'm thinking all those bindings would get really big in a large app and would be a source of svn workflow conflicts.

Comment by glenview...@gmail.com, May 21, 2011

Please omit the apostrophe from "it's" in the sentence "To construct an object, you first build it's dependencies."

Comment by volpegab...@gmail.com, Jun 2, 2011

I have same Hobbss's question:

"I have spent days looking at guice wiki and the many posts of people with problems (e.g. when the singleton is not a singleton, or how to manually avoid creating multiple injectors etc. What about this one? http://markmail.org/message/eb6osvv5cbk4g6zr this would frighten off most people).

I still dont get it. I cant look at a guice example and guess whats actually happening.

The factory and singleton pattern are so simple, and so easy to understand/use/debug, I just cant see the compulsion to use a "magic" framework which makes understanding exactly whats going on very difficult, and code hard to debug. Explicit simplicity over implicit complexity any day, even if I have to write some extra lines of easy to follow code.

Is rigidly defined modularity, e.g. using Guice injection for everything, worth the cost of learning/using/debugging a new framework into your code, rather than just making your software modular by design with out it? The complexity increase certainly isnt worth saving some lines of code.

This reminds me of EJB again - eveyone was doing it (including us), then when we relised it made our code slower/harder to write and maintain, the whole thing was dropped.

Or is it just me?"

Comment by jonathon...@gmail.com, Jul 26, 2011

@hob and volpegab,

You guys should read up on dependency injection. Actually, just watching the video that's on the home of this project page will clarify why overuse of singletons and factories are a Bad Thing(tm)... or at least a less desirable thing. You can also read the motivation article.

In essence, you're tying your code down to a concrete specific implementation (tight coupling), significantly narrowing the contexts in which it can be reused. It also makes testing difficult, to say the least because if you have two components that are tightly-coupled, you will probably have to test them both at the same time, or you at least you won't be able to test one without having the other around too.

Comment by kroh.and...@gmail.com, Sep 30, 2011

This document should contain information on what jars are required to be on the classpath based on the features being used.

Comment by piroxxi, Oct 22, 2011

+1 to andrew

When downloading the .zip, there is many .jars and I didn't knew which one to choose. Finaly, I simply added guice-3.0.jar and javax.inject.jar in war/WEB-INF/lib, and it worked fine. But many examples also included aopalliance.jar .

Comment by ricky.he...@gmail.com, Nov 1, 2011

I think that this page and many others should include which jars that are used to do the things presented.

Comment by cl...@verdoes.se, Nov 24, 2011

What makes RealBillingService? "real"? To me it looks like the injector configuration determines the behavior of the BillingService?. If BillingModule? maps CreditCardProcessor?.class to MyMockProcessor?.class, RealBillingService? would become a "mock" BillingService?, right? I.e. wouldn't BillingService? and RealBillingModule? be better names (using MockBillingModule? when testing)? Or am I missing something?

Comment by cgdec...@gmail.com, Nov 24, 2011

"Real" here means the production implementation of BillingService?. Using a mock CreditCardProcessor? doesn't make RealBillingService? less real... it doesn't care what dependency implementations it's using.

Comment by wiwi1...@gmail.com, Dec 7, 2011

simple but clear.

Comment by ian.g.si...@gmail.com, Jan 24, 2012

Wouldn't you want to ask the injector for an instance of BillingService? rather than its implementation? It works just the same; I just did the example on my machine.

Comment by q492441...@gmail.com, May 17, 2012

how many guys use this ?


Sign in to add a comment
Powered by Google Project Hosting