Работает внутри инжектора Guice, @Injects не уважается в классе `new` - PullRequest
1 голос
/ 25 мая 2011

У нас есть Swing-приложение, которое мы хотели бы добавить к использованию Guice-3.0.Наша причина состоит в том, чтобы перевести наши старые фабрики во что-то более гибкое.

Я гарантировал, что приложение работает внутри инжектора, и теперь мы хотим, чтобы у класса был путь вниз, есть некоторые поля @ Inject'ed кажется моему неопытному глазу, что аннотации @Inject для этого класса игнорируются при запуске «new».

Вопрос теперь заключается в том, правильно ли я понял, что классы создаются новыми, когдапри первом запуске внутри инжектора Guice гарантированно учитываются их аннотации @Inject или если это свойство теряется после одного или нескольких новых в вашем коде.

Другими словами:

Если A получает экземпляр B от Guice, а B затем создает new C(), который, в свою очередь, запускает new D(), а D имеет внутри @ Inject, должен ли D обрабатываться Guice?

Если да, как я могу добавить код в мою конфигурацию Guice, который позволяет мне видеть, что "new X ()" обрабатывается Guice и что "@Inject setY (Y y)" выполняется?Я не против, если этот журнал будет очень большим - мне просто нужно убедиться, что Guice работает так, как я ожидаю.

Ответы [ 2 ]

7 голосов
/ 25 мая 2011

Нет, ничего , созданный с помощью new напрямую, обрабатывается Guice ... он не делает магию. Guice должен работать так, как будто он создает ваши графы объектов для вас. Вы не должны ссылаться на Injector в своих классах, и вы не должны использовать new для создания служб, которые вы хотите внедрить.

Вот некоторые варианты, которые вы можете иметь:

  • Внедрить C в B вместо new. Введите D в C.
  • Если вам нужно создать один или оба из них несколько раз в классе, в котором вы в данный момент new вводите их, вместо этого введите Provider<C> или Provider<D> и используйте get() вместо new.
  • Если есть объекты, доступные только во время выполнения, которые необходимо передать этим классам (например, что-то, основанное на пользовательском вводе или данных из других мест) для их создания, вам может понадобиться использовать Assisted Inject и ввести CFactory DFactory вместо Provider.
  • Если вы действительно не можете найти лучшего способа, вы можете использовать injector.injectMembers(Object) для инъекции объектов, которые вы создали с помощью new ... но трудно сказать, помогает ли Guice вам, если вы делаете что.
4 голосов
/ 26 мая 2011

Как указал ColinD, в вашем примере D не будет создан Guice. Вызов new для объекта создаст его вне Guice DI. Если вы хотите подтвердить, что что-то создается с помощью Guice, вы можете добавить ведение журнала в методы сеттера @Inject или, если вы делаете инъекцию в конструктор, вы можете добавить новый метод только для целей ведения журнала:

@Inject
public void log() {
    logger.debug(//check if injected classes have been set)
    ...
}

Переоборудовав большое приложение Swing для использования Guice и написав новое с нуля, нужно помнить несколько вещей.

1) Guice не был предназначен для настольных приложений. Он был создан для использования на серверах. Время запуска не то, что было принято во внимание. После полной конвертации приложения Swing со всех статических фабрик во все Guice оно добавило ~ 30/60 секунд к времени запуска в зависимости от того, был ли это холодный или теплый запуск.

2) Очень сложно добавить только немного Guice. Теперь, когда вы обнаруживаете, вам быстро понадобится зависимость от созданного класса на три уровня глубиной, и вам придется либо преобразовать все это в Guice, либо начать передавать множество классов через конструкторы и добавить геттеры

3) Остерегайтесь нетерпеливо создавать объекты с помощью Guice. @Singleton по умолчанию с готовностью создает объект при запуске. Это может иметь катастрофические последствия для времени запуска приложения. Если вы беспокоитесь об этом, на форуме Guice есть хорошая ветка о создании @EagerSingleton или @LazySingleton, которую вы можете захотеть проверить

4) С учетом всего сказанного, Guice довольно крутой, просто нужно знать, как он работает, чтобы добиться хорошей производительности с ним в настольном приложении

...