Search code examples
guice

Is @Provides necessary with @Named parameter?


Say, I have a module something like below:

public class TestModule extends AbstractModule {

    @Override
    protected void configure() {

    }

    @Provides
    @Singleton
    public A getA(final B b) {
        A a = new A(b, getC());
        return a;
    }

    @Provides
    @Singleton
    private B getB(@Named("someName") final String someName) {
            ......
    }

    private C getC() {
        .....
    }
}

The question here is if B is only used within TestModule, then do I need @Provides and @Singleton for getB or not. I am not sure with @Named as parameter, do I need @Provides on method or not.

Because if I don't need it, then I can simply remove all the annotations on getB and it would be simply as follows:

public class TestModule extends AbstractModule {

    @Override
    protected void configure() {

    }

    @Provides
    @Singleton
    public A getA() {
        A a = new A(getB(), getC());
        return a;
    }

    private B getB(@Named("someName") final String someName) {
            ......
    }

    private C getC() {
        .....
    }
}

Solution

  • It might help to read this like a sentence:

    @Provides
    @Singleton
    @Named("someName")
    B getB(SomeArg arg, SomeOtherArg other) {
      //make the thing
    }
    

    "This method @Provides a @Singleton which is @Named someName, with type B. Here are the things which are used to make it (method params), and here is how you go about building it (method body)."

    @Provides
    B getB(@Named("someName") final String someName) {
      //make the thing
    }
    

    "This method @Provides an instance of B. In order to create it, a String which is @Named "someName" will be required, and here is how you go about building it (method body)."

    Note that @Named, like any other qualifier, can be annotated not only on the method, but on the arguments, in effect saying "does this describe the thing being provided" or "does this describe the thing which is required". The presence of it is not sufficient to mark a method as a provider.

    The annotation @Provides is required for a method which should be called to create that bound type, so is not optional. The annotation @Singleton is technically optional, but omitting it means that the instance returns will not be a singleton, which may or may not make sense for your needs. If not needed, general best practice is to avoid making something a singleton.