|
ProvidesMethods
@Provides MethodsWhen 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 ExceptionsGuice 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. | |
This only works with Guice 2.
You can also annotate the method with a scope, like @Singleton or @RequestScoped.
limpbizkit,
Excellent point, but I suggest you update the wiki document with such an example in case users skip the comments.
Why can't we use more than one binding annotation per @Provides method ?
What would the goal of multiple binding annotations be?
If we annotate with scope, will class be instantiate in a lazy way ?
Is there any way using @Provides to provide a Singleton?
Yes. Annotate the method with @Singleton.
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?
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?
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) { ...Who should be the responsable of release a resource provided by a Provider/Provider Method?, i. e. a Connection. The module? The aplication?
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.