如何将几个接口收集到HK2中的Collection中?

时间:2015-12-01 13:43:45

标签: java dependency-injection hk2

我有AbstractBinder并且使用相同的接口绑定了几个类。我们假设绑定FishCat,它们都实现了Animal接口。

将这些注入到Collection<Animal>的bean中的最简单/最合适的方法是什么?

PS:Spring在简单@Autowire List<Animal>中具有等效性,并且该集合由Spring创建并填充。

2 个答案:

答案 0 :(得分:2)

HK2有IterableProvider<T>,如上所述here in the documentation。您可以按by name获取服务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注入其中,并从那里返回列表。例如

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) {}
}

是的,这是一些额外的工作。

答案 1 :(得分:2)

在最新版本的hk2(2.4.0)中,您可以

@Inject Iterable<Foo> foos;

这可以让你保持你的pojo没有任何hk2 API。

有关详细信息,请参阅:Iterable Injection