I would like to bind a unique singleton instance for each annotation as shown below, such that Client1.a != Client1.b and Client1.a == Client2.a.
class X {}
@Singleton class OneOfEachAnnotation {
@Inject OneOfEachAnnotation(X x) { }
}
class Client1 {
@Inject Client(@A OneOfEachAnnotation a, @B OneOfEachAnnotation b) {}
}
class Client2 {
@Inject Client(@A OneOfEachAnnotation a, @B OneOfEachAnnotation b) {}
}
This answer seems to claim that I can accomplish the binding like this, but when I do so, Client1.a == Client1.b.
bind(OneOfEachAnnotation.class).annotatedWith(A.class).to(OneOfEachAnnotation.class).in(Singleton.class);
bind(OneOfEachAnnotation.class).annotatedWith(B.class).to(OneOfEachAnnotation.class).in(Singleton.class);
Thanks to Sam Berlin at Google Groups Guice forum. The reason this doesn’t work is because the OneOfEachAnnotation is already annotated with @Singleton. Removing the @Singleton annotation fixes the problem.
Sam explained why:
The statements:
are saying, “Create a binding from
@A OneOfEachAnnotationtoOneOfEachAnnotationand make the@A OneOfEachAnnotationa singleton.” Same thing with@B.Ignoring the
@SingletononOneOfEachAnnotationfor a second (assuming it didn’t exist), then this would have the behavior of:User injects
OneOfEachAnnotation(unannotated) multiple times: a new one is created each time, because that binding is unscoped.User injects
@A OneOfEachAnnotation, the first time it links down to the unannotatedOneOfEach, sees it needs to be constructed, and constructs it. The second time the binding is already provisioned, soScopes.SINGLETONdoesn’t go to the linked binding again.(Same thing with
@Bas@A.)When
OneOfEachAnnotationhas@Singletonon it, then Guice thinks that the unscoped value is also a singleton. So when@Alinks to the unannotated, it will create the first instance. When@Blinks down the unannotated, Guice notices that the unannotated version, also a Singleton, has already been constructed, and returns that instance.