问题
I have a project that provides an interface, let's call it IImplementMe, which i want to inject into my project. This interface will be implemented by various producers, so I need to inject all implementations. I am trying to use TypeLiteral for this.
Here is the code of the producer :
@Singleton
public class SomeImplementation implements IImplementMe {
private final String value;
@Inject
public SomeImplementation(final SomeOtherConfig configuration) {
this.value= configuration.getValue();
}
@Override
public String getValue() {
return value;
}
}
And in my registry class I have register(IImplementMe.class).to(SomeImplementation.class);
Then, in my project I inject it like this :
@Inject
public SomeEndpoint(final List<IImplementMe> implementations){
///
}
and i bind it like
private static class MarketDataSetTypeLiteral extends TypeLiteral<List<IImplementMe>> {
}
bind(new MarketDataSetTypeLiteral()).toRegistry();
I made sure my SomeIMplementation constructor gets called, but in my endpoint the List is empty, so no implementation is provided. I'm using guice for injection. Any ideas ?
LE: It turns out that the provided implementation is created after my endpoint class is created (at creation time it injects a reference of an empty list). Later in the lifecycle the reference is updated with the implementation, so I actually have access to it after guice does it's stuff.
I'm guessing it's due to the maven dependencies, and how guice handles the instantiations. Since the producer must have a dependency on my project, I guess it makes sense it gets instantiated last, thus causing my initial problem.
回答1:
You are looking for multibindings -> https://github.com/google/guice/wiki/Multibindings
public class IImplementMeModule extends AbstractModule {
public void configure() {
Multibinder< IImplementMe > uriBinder = Multibinder.newSetBinder(binder(), IImplementMe.class);
uriBinder.addBinding().to(SomeImplementationOfIImplementMe.class);
uriBinder.addBinding().to(AnotherImplementationOfIImplementMe.class);
... // bind plugin dependencies, such as our Flickr API key
}
}
Then you can inject the set of IImplemetnMe
as following
@Inject TweetPrettifier(Set<IImplemetnMe> implementations)
I would suggest you to have a look at MapBindings which allows you provide keys for each implementation and then you will be able to inject your bindings as a Map
来源:https://stackoverflow.com/questions/36690178/java-inject-implementation-using-typeliteral