HK2中如何将多个接口收集到一个Collection中?
How to collect several interfaces into a Collection in HK2?
我有我的 AbstractBinder
并且我用相同的界面绑定了多个 类。假设我绑定了 Fish
和 Cat
,它们都实现了 Animal
接口。
将它们注入需要 Collection<Animal>
的 bean 的 easiest/proper 方法是什么?
PS:Spring 等价于 @Autowire List<Animal>
,集合由 Spring.
创建和填充
HK2 有 IterableProvider<T>
, as mentioned here in the documentation. You can get the service by name, by qualifier annotation,或者只是迭代它们,因为它是一个 Iterable
。只是为了好玩,这里有一个测试。
public class IterableProviderTest {
public static interface Service {}
public static class ServiceOne implements Service {}
@QualAnno
public static class ServiceTwo implements Service {}
@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public static @interface QualAnno {
public static class Instance
extends AnnotationLiteral<QualAnno> implements QualAnno {
public static QualAnno get() {
return new Instance();
}
}
}
public class Binder extends AbstractBinder {
@Override
protected void configure() {
bind(ServiceOne.class).to(Service.class).named("one");
bind(ServiceTwo.class).to(Service.class).qualifiedBy(QualAnno.Instance.get());
}
}
@Inject
private IterableProvider<Service> services;
@Test
public void test_IterableProvider() {
ServiceLocator locator = ServiceLocatorUtilities.bind(new Binder());
locator.inject(IterableProviderTest.this);
assertEquals(2, services.getSize());
Service serviceOne = services.named("one").get();
assertTrue(serviceOne instanceof ServiceOne);
Service serviceTwo = services.qualifiedWith(QualAnno.Instance.get()).get();
assertTrue(serviceTwo instanceof ServiceTwo);
}
}
更新
对于 List<Service>
(避免 HK2 InterablProvider),我唯一能想到的就是使用 Factory
并将 IterableProvider
注入其中,然后从那里 return 列表。例如
public class Binder extends AbstractBinder {
@Override
protected void configure() {
...
bindFactory(ListServiceFactory.class).to(new TypeLiteral<List<Service>>(){});
}
}
public static class ListServiceFactory implements Factory<List<Service>> {
@Inject
private IterableProvider<Service> services;
@Override
public List<Service> provide() {
return Lists.newArrayList(services);
}
@Override
public void dispose(List<Service> t) {}
}
是的,这是一些额外的工作。
在最新版本的hk2(2.4.0)中可以
@Inject Iterable<Foo> foos;
这样您就可以保留没有任何 hk2 API 的 pojo。
有关详细信息,请参阅:Iterable Injection
我有我的 AbstractBinder
并且我用相同的界面绑定了多个 类。假设我绑定了 Fish
和 Cat
,它们都实现了 Animal
接口。
将它们注入需要 Collection<Animal>
的 bean 的 easiest/proper 方法是什么?
PS:Spring 等价于 @Autowire List<Animal>
,集合由 Spring.
HK2 有 IterableProvider<T>
, as mentioned here in the documentation. You can get the service by name, by qualifier annotation,或者只是迭代它们,因为它是一个 Iterable
。只是为了好玩,这里有一个测试。
public class IterableProviderTest {
public static interface Service {}
public static class ServiceOne implements Service {}
@QualAnno
public static class ServiceTwo implements Service {}
@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public static @interface QualAnno {
public static class Instance
extends AnnotationLiteral<QualAnno> implements QualAnno {
public static QualAnno get() {
return new Instance();
}
}
}
public class Binder extends AbstractBinder {
@Override
protected void configure() {
bind(ServiceOne.class).to(Service.class).named("one");
bind(ServiceTwo.class).to(Service.class).qualifiedBy(QualAnno.Instance.get());
}
}
@Inject
private IterableProvider<Service> services;
@Test
public void test_IterableProvider() {
ServiceLocator locator = ServiceLocatorUtilities.bind(new Binder());
locator.inject(IterableProviderTest.this);
assertEquals(2, services.getSize());
Service serviceOne = services.named("one").get();
assertTrue(serviceOne instanceof ServiceOne);
Service serviceTwo = services.qualifiedWith(QualAnno.Instance.get()).get();
assertTrue(serviceTwo instanceof ServiceTwo);
}
}
更新
对于 List<Service>
(避免 HK2 InterablProvider),我唯一能想到的就是使用 Factory
并将 IterableProvider
注入其中,然后从那里 return 列表。例如
public class Binder extends AbstractBinder {
@Override
protected void configure() {
...
bindFactory(ListServiceFactory.class).to(new TypeLiteral<List<Service>>(){});
}
}
public static class ListServiceFactory implements Factory<List<Service>> {
@Inject
private IterableProvider<Service> services;
@Override
public List<Service> provide() {
return Lists.newArrayList(services);
}
@Override
public void dispose(List<Service> t) {}
}
是的,这是一些额外的工作。
在最新版本的hk2(2.4.0)中可以
@Inject Iterable<Foo> foos;
这样您就可以保留没有任何 hk2 API 的 pojo。
有关详细信息,请参阅:Iterable Injection