My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
ProvidesMethods  
Updated Oct 16, 2011 by sberlin

@Provides Methods

When you need code to create an object, use an @Provides method. The method must be defined within a module, and it must have an @Provides annotation. The method's return type is the bound type. Whenever the injector needs an instance of that type, it will invoke the method.

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

  @Provides
  TransactionLog provideTransactionLog() {
    DatabaseTransactionLog transactionLog = new DatabaseTransactionLog();
    transactionLog.setJdbcUrl("jdbc:mysql://localhost/pizza");
    transactionLog.setThreadPoolSize(30);
    return transactionLog;
  }
}

If the @Provides method has a binding annotation like @PayPal or @Named("Checkout"), Guice binds the annotated type. Dependencies can be passed in as parameters to the method. The injector will exercise the bindings for each of these before invoking the method.

  @Provides @PayPal
  CreditCardProcessor providePayPalCreditCardProcessor(
      @Named("PayPal API key") String apiKey) {
    PayPalCreditCardProcessor processor = new PayPalCreditCardProcessor();
    processor.setApiKey(apiKey);
    return processor;
  }

Throwing Exceptions

Guice does not allow exceptions to be thrown from Providers. Exceptions thrown by @Provides methods will be wrapped in a ProvisionException. It is bad practice to allow any kind of exception to be thrown -- runtime or checked -- from an @Provides method. If you need to throw an exception for some reason, you may want to use the ThrowingProviders extension @CheckedProvides methods.

Comment by bluepenguin, Apr 25, 2009

This only works with Guice 2.

Comment by project member limpbiz...@gmail.com, Oct 11, 2009

You can also annotate the method with a scope, like @Singleton or @RequestScoped.

Comment by gili.tza...@gmail.com, Oct 13, 2009

limpbizkit,

Excellent point, but I suggest you update the wiki document with such an example in case users skip the comments.

Comment by biethb@gmail.com, Apr 14, 2010

Why can't we use more than one binding annotation per @Provides method ?

Comment by project member sberlin, Apr 15, 2010

What would the goal of multiple binding annotations be?

Comment by goudreau...@gmail.com, Apr 24, 2010

If we annotate with scope, will class be instantiate in a lazy way ?

Comment by jerzy.cz...@gmail.com, Apr 27, 2010

Is there any way using @Provides to provide a Singleton?

Comment by sa...@google.com, Apr 27, 2010

Yes. Annotate the method with @Singleton.

Comment by albertattard, Oct 31, 2010

Hi,

What if the provider throws an exception?

Let say, for example, the "new DatabaseTransactionLog?()" throws a DatabaseException? (or anything), how should this be handled?

Comment by andrew.s...@gmail.com, Dec 13, 2010

Is there some way to override the scope of the Provider specified by a @Provides method either in #configure() or in a derived class?

For instance, let's say you define a @Provides method with default scope, but then want to make another version of the Module which applies @Singleton scope to this method. How might you specify this override?

Comment by ashwin.jayaprakash, Aug 21, 2011

How do you use this (below) on the @Inject side? What do you annotate as @Named("PayPal API key")?

@Provides @PayPal
  CreditCardProcessor providePayPalCreditCardProcessor(
      @Named("PayPal API key") String apiKey) {
...
Comment by cristian...@gmail.com, Sep 7, 2011

Who should be the responsable of release a resource provided by a Provider/Provider Method?, i. e. a Connection. The module? The aplication?

Comment by kaz.r...@gmail.com, Sep 14, 2011

Here is how I've used it;

I had to have providers for IFoo which needed to return different impl old vs new,

in my module, I added providers like

@Provides @Named("old") IFoo getFoo() { . }

and

@Provides @Named("new") IFoo getFoo() { . }

On injector site, couple of ways to get desired IFoo

Using constructor

@Inject MyObj?(@Named("old") IFoo foo) { this.foo = foo; }

or explicitly using injector to get desired instance

IFoo foo = injector.getInstance(Key.get(IFoo.class, Names.named("old")));

injector is of course injected in calling class :)

Hope this helps.


Sign in to add a comment
Powered by Google Project Hosting