Как получить все разработчики/подклассы интерфейса с Guice?

С помощью 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() для A и B в YourInterface. Если вы хотите получить более "прозрачное" (автоматическое) решение, например, то, что AFAIK Spring предлагает готовое предложение, тогда предполагается, что Guice уже знает о A и B, потому что у вас уже есть привязка для A и B в любом другом месте, даже если они не явные, а просто неявные, например через @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);
   }
}

Обратите внимание, что этот подход НЕ требует сканирования классов; он просто просматривает все уже известные привязки в инжекторе для чего-то, что IS-A YourInterface.