Google Guice - классы должны иметь один (и только один) конструктор, аннотированный @Inject, или конструктор с нулевым аргументом, который не является закрытым - PullRequest
0 голосов
/ 27 апреля 2020

все

У меня есть несколько вопросов, касающихся Google Guice. Любая помощь приветствуется.

У меня есть интерфейс обработчика и его реализация.

public interface Handler {
   void handle();
}
public class HandlerImpl implements Handler {
   private Filter filterOne;

   @Override
   void handler() {
     filterOne.foo();
   }
}

Фильтр - это другой интерфейс:

public interface Filter {
   void foo();
}

Есть несколько вариантов его реализации.

public class FilterOne implements Filter {
   void foo() {
   }
}

public class FilterTwo implements Filter {
   void foo() {
   }
}

Затем в моем модуле Guice:

public class HandlerModule extends AbstractModel {

  @Override
  protected void configure() {
     bind(Handler.class).to(HandlerImpl.class);
  }

  @Provides
  @Singleton
  public Handler provideHandler(@Named("filterOne")filter filterOne) {
    return new HandlerImpl(filterOne);
  }

  @Provides
  @Singleton
  @Named("filterOne")
  public Filter provideFilterOne() {
    return new FilterOne();
  }

  @Provides
  @Singleton
  @Named("filterTwo")
  public Filter provideFilterTwo() {
    return new FilterTwo();
  }
}

В приведенной выше реализации я всегда получаю сообщение об ошибке - Не удалось найти подходящий конструктор в HandlerImpl. Классы должны иметь либо один (и только один) конструктор, аннотированный @Inject, либо конструктор с нулевым аргументом, который не является закрытым.

Я использую @Named, чтобы отличать два фильтра. Я использую это неправильно? Это потому, что у меня есть две реализации Filter, и Guice не может сказать, какую из них использовать при попытке предоставить HandlerImpl?

1 Ответ

0 голосов
/ 01 мая 2020

Вы связываете Handler.class дважды:

  • В configure() метод: bind(Handler.class).to(HandlerImpl.class);
  • В качестве поставщика:
  @Singleton
  public Handler provideHandler(@Named("filterOne")filter filterOne) {
    return new HandlerImpl(filterOne);
  }

Первая из этих привязок не может работать, так как HandlerImpl не имеет конструктора, помеченного @Inject. Однако, если вы исправите это, он все равно не будет работать - вы не можете предоставить несколько привязок для одного и того же ключа.

TL; DR: удалите bind(Handler.class).to(HandlerImpl.class); из метода configure()

...