As far as I know, they are exactly equivalent for most simple cases.
/** * Class-style provider. * In module: bind(Foo.class).annotatedWith(Quux.class).toProvider(MyProvider.class); */ class MyProvider implements Provider<Foo> { @Inject Dep dep; // All sorts of injection work, including constructor injection. @Override public Foo get() { return dep.provisionFoo("bar", "baz"); } } /** * Method-style provider. configure() can be empty, but doesn't have to be. */ class MyModule extends AbstractModule { /** Name doesn't matter. Dep is injected automatically. */ @Provides @Quux public Foo createFoo(Dep dep) { return dep.provisionFoo("bar", "baz"); } @Override public void configure() { /* nothing needed in here */ } }
In any style, Guice allows you to enter Foo and Provider<Foo> , even if the key is bound to a class or instance. Guice automatically calls get if you get the instance directly and creates an implicit Provider<Foo> if it does not exist. Link annotations work in both styles.
The main advantage of @Provides is its compactness, especially compared to the anonymous internal implementations of the provider. Please note, however, that there may be several cases where you would like to use provider classes:
You can create your own long-term instances of the provider, possibly with constructor parameters, and bind keys to these instances, and not to class literals.
bind(Foo.class).toProvider(new FooProvisioner("bar", "baz"));
If you use a framework compatible with JSR 330 (javax.inject), you can easily bind to classes or instances of javax.inject.Provider. com.google.inject.Provider extends this interface.
bind(Foo.class).toProvider(SomeProviderThatDoesntKnowAboutGuice.class);
Your provider may be sophisticated enough to factor into your class. Depending on how you structured your tests, it may be easier to test your provider in this way.
Providers can extend abstract classes. This may not be easy or intuitive for this using the @Provides methods.
You can directly associate multiple keys with the same provider. Each @Provides method creates exactly one binding, although you can associate other keys with a key (here @Quux Foo) and let Guice do a second search.
Providers easily decorate or wrap if you want to (for example) cache or memoize instances without using Guice regions or bindings.
bind(Foo.class).toProvider(new Cache(new FooProvisioner("bar", "baz")));
IMPORTANT Although this is a good strategy for classes that Guice cannot create, remember that Guice can automatically create and enter a Provider<T> for any T that you bind in any way, including the class name, key, or instance. There is no need to create an explicit provider if the actual logic of your own participation does not exist.
source share