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

2022-09-01 20:42:04

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

在Guice中是否有等效的?或者使用扩展点来添加此行为?


答案 1

这看起来像是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) {
        ...
    }
}

这应该与你需要的相匹配。


答案 2

Guice Multibindings 要求您显式地将Binding() for & to .如果你想要一个更“透明”(自动)的解决方案,比如AFAIK Spring提供的开箱即用的解决方案,那么假设Guice已经知道了&因为你已经有一个绑定&other,即使不是显式的,而只是隐含的,例如通过其他地方,然后,只有这样,你才能使用这样的东西进行自动发现(灵感来自这里完成, 基于在模块中访问 Guice 注入器):ABYourInterfaceABAB@Inject

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

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


推荐