在我的应用程序中,我需要根据一些用户输入获取不同的实现。
由于我想充分利用HK2的优势,所以我想用Jersey / HK2提供的方法解决这个问题。
到目前为止,我所做的只是通过接口绑定服务,这些接口使用ApplicationConfig
和ApplicationBinder
绑定到启动时的实现:
@javax.ws.rs.ApplicationPath("api")
public class ApplicationConfig extends ResourceConfig
{
public ApplicationConfig()
{
super();
packages(true, "my.package");
register(new ApplicationBinder());
register(....);
....
}
}
public class ApplicationBinder extends AbstractBinder
{
@Override
protected void configure()
{
bind(ServletTemplateLoader.class).to(TemplateLoader.class);
bindAsContract(JobsImpl.class);
bindAsContract(JobInputAppender.class);
bindAsContract(ParamNameMapper.class);
bind(RedisJobRepository.class).to(JobRepositoryInterface.class);
....
}
现在,我需要根据用户输入动态获取一个实现。有25种不同的实现方式都使用同一接口。
这意味着,我不能再简单地使用bind.to
方法了。相反,我认为我需要分别向bindAsContract
注册它们。
但是,我该如何为任何给定的输入(来自用户)编写一个方法/类为我提供正确的实现?
本质上,我需要一种如下所示的方法:
public interface MyInterface {}
public class Type1Impl implements MyInterface {} // registered with `bindAsContract`
public MyInterface getImplementation(final String type_)
{
switch (type_) {
case "type1":
return // what to do here to get "my.package.Type1Impl" instance?
case "type":
....
}
}
我需要实例来自HK2,因为Impl也使用注入服务,因此我不能简单地动态创建新实例。
答案 0 :(得分:2)
我认为使用IterableProvider会有更好的答案。基本上,您可以在一项服务中做到这一点:
AdminClient
.create(props)
.listTopics()
.names()
.toCompletableFuture
.asScala
希望这会有所帮助!
答案 1 :(得分:0)
因此,经过数小时的搜索却没有答案,我感到沮丧和盘旋,想着“好吧,尽力去做你能想到的最明显的事情”。
在DI的情况下,只是告诉容器给我我想要的东西。
事实证明,这种方法行之有效,而且几乎是无足轻重的……
public interface MyInterface {}
public class Type1Impl implements MyInterface {}
public class Type2Impl implements MyInterface {}
@javax.ws.rs.ApplicationPath("api")
public class ApplicationConfig extends ResourceConfig
{
public ApplicationConfig()
{
super();
packages(true, "my.package");
register(new ApplicationBinder());
}
}
public class ApplicationBinder extends AbstractBinder
{
@Override
protected void configure()
{
bindAsContract(ImplementationGetter.class);
bind(Type1Impl.class).to(MyInterface.class).named("type1");
bind(Type2Impl.class).to(MyInterface.class).named("type2");
}
}
public class ImplementationGetter {
@Inject
private ServiceLocator _locator;
public MyInterface getImplementation(final String type_)
{
switch (type_) {
case "type1":
return _locator.getService(MyInterface.class, "type1");
case "type2":
return _locator.getService(MyInterface.class, "type2");
}
}
}