如何使用Guice获取接口的所有实现者/子类?

时间:2011-05-22 00:03:40

标签: java guice

使用Spring,您可以定义一个数组属性,并让Spring注入从给定类型派生的每个(@Component)类中的一个。

Guice中有相同的效果吗?或者是一个添加此行为的扩展点?

3 个答案:

答案 0 :(得分:15)

这看起来像Guice MultiBinder的用例。你可能有类似的东西:

interface YourInterface {
    ...
}

class A implements YourInterface {
    ...
}

class B implements YourInterface {
    ...
}

class YourModule extends AbstractModule {
    @Override protected void configure() {
        Multibinder.newSetBinder(YourInterface.class).addBinding().to(A.class):
        Multibinder.newSetBinder(YourInterface.class).addBinding().to(B.class):
    }
}

你可以在任何地方注入Set<YourInterface>

class SomeClass {
    @Inject public SomeClass(Set<YourInterface> allImplementations) {
        ...
    }
}

这应该符合你的需要。

答案 1 :(得分:11)

Guice Multibindings要求您为A&amp;显式添加绑定() BYourInterface。如果你想要一个更透明的&#34; (自动)解决方案,例如AFAIK Spring开箱即用,然后假设Guice已经了解A&amp; B,因为您已经拥有A&amp;的约束力无论如何,B在其他地方,即使不明确但只是隐含的,例如通过其他地方的@Inject,然后您可以使用此类内容进行自动发现(inspired by as done here,基于accessing Guice injector in a Module):

class YourModule extends AbstractModule {
   @Override protected void configure() { }

   @Provides
   @Singleton
   SomeClass getSomeClass(Injector injector) {
       Set<YourInterface> allYourInterfaces = new HashSet<>();
       for (Key<?> key : injector.getAllBindings().keySet()) {
           if (YourInterface.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
            YourInterface yourInterface = (YourInterface) injector.getInstance(key);
            allYourInterfaces.add(yourInterface);
       }
       return new SomeClass(allYourInterfaces);
   }
}

再次注意,此方法不需要任何类路径扫描;它只是查看Injector中所有IS-A YourInterface的已知绑定。

答案 2 :(得分:1)

科特林

Class SomeModule : AbstractModule() {
        
            override fun configure() {
                val myBinder: Multibinder<MyInterface> = Multibinder.newSetBinder(binder(), MyInterface::class.java)
                myBinder.addBinding().to(Implementation1::class.java)
                 myBinder.addBinding().to(Implementation2::class.java)
}

使用

@Inject constructor(private val someVar:Set<@JvmSuppressWildcards MyInterface>)