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

Ada*_*erg 18 java guice

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

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

jfp*_*ret 18

这看起来像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):
    }
}
Run Code Online (Sandbox Code Playgroud)

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

class SomeClass {
    @Inject public SomeClass(Set<YourInterface> allImplementations) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该符合你的需要.


vor*_*ger 11

吉斯Multibindings要求你明确addBinding()为A&BYourInterface.如果您想更"透明"(自动)解决方案,比如什么AFAIK Spring提供外的开箱,再假设吉斯已经知道AB因为你已经有一个绑定AB即使没有明确的其他地方,无论如何,但只是通过@Inject其他地方隐含,然后你才可以使用这样的东西进行自动发现(灵感来自于这里所做的,基于访问模块中的Guice注入器):

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);
   }
}
Run Code Online (Sandbox Code Playgroud)

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