Как использовать инжектор Guice?

Я изучаю Guice и не совсем понимаю, как использовать экземпляр Injector. Лучше создать экземпляр Injector один раз при загрузке приложения и сделать его общедоступным синглтоном?

И правда ли, что мы всегда должны использовать Injector#getInstance(SomeClass.class) для получения классов, в которые мы поместили аннотации Guice @Inject?


person MyTitle    schedule 12.02.2013    source источник
comment
Лучше вообще не использовать Injector.getInstance().   -  person millimoose    schedule 12.02.2013
comment
@millimoose, но как еще можно получить классы, управляемые Guice?   -  person MyTitle    schedule 12.02.2013
comment
Поля, аннотированные @Inject, должны иметь автоматически доступные классы. (Предположим, что Guice управляет классами, которым требуется внедрение.) Идея состоит в том, что у вас есть контейнер, управляющий обеими вашими зависимостями, и классами, которые их используют, и извлекает только один основной класс из инжектора. вручную, чтобы запустить приложение. Вам также следует рассмотреть возможность перечитать руководство, это внедрение зависимостей 101.   -  person millimoose    schedule 12.02.2013
comment
Да, я прочитал его перед тем, как задать вопрос, но класс с полями, помеченными @Inject, должен быть получен с использованием Injector#getInstance(MyClass.class). Так что, если у меня есть несколько классов с полями, аннотированными @Inject? Мне нужно инициировать каждый класс, используя Injector#getInstance(ClassName.class).   -  person MyTitle    schedule 12.02.2013
comment
Ах. Не обязательно. Только если вам нужно вызвать метод из класса, которым не управляет Guice. В качестве альтернативы вы можете вместо этого сделать Injector.injectMembers(this) и заполнить все поля, аннотированные @Inject из Injector, даже для неуправляемого объекта.   -  person millimoose    schedule 13.02.2013
comment
Да, я вызываю класс, управляемый guice, из класса, который ничего не знает о guice (поэтому он не работает). Я тестировал Injector.injectMembers(this). Как я понимаю, мне нужно вызывать этот метод в каждом классе, который имеет аннотации @Inject?   -  person MyTitle    schedule 13.02.2013
comment
Нет, только для объектов, которые не управляются Guice.   -  person millimoose    schedule 13.02.2013


Ответы (1)


Вы не должны передавать инжектор как глобальный синглтон. Вы смотрели: https://github.com/google/guice/wiki/GettingStarted? Обратите внимание, что RealBillingService не использует инжектор для получения экземпляров CreditCardProcessor и TransactionLog. Вместо этого Guice обрабатывает все это за вас при создании экземпляра.

Если вы находитесь в ситуации, когда вам нужно, чтобы Guice создал множество объектов одного типа, рассмотрите возможность использования провайдера. и внедрение этого провайдера.

person condit    schedule 12.02.2013
comment
Да, я понимаю. Но что, если у меня есть несколько сервисов, таких как RealBillingService, и у каждого из них есть аннотации @Inject для внедрения объектов CreditCardProcessor и TransactionLog. Поэтому мне нужно использовать Injector#getInstance для каждой службы, например RealBillingService. Но я хочу создавать эти сервисы в разных местах, поэтому у меня есть 2 варианта: создать объект Injector в каждом месте и использовать Injector#getInstance для получения необходимого сервиса или для создания экземпляра Injector, как только он станет доступным (глобальный синглтон) во все места, где мне это нужно. - person MyTitle; 12.02.2013
comment
Или иметь третий объект, содержащий экземпляры двух ваших служб (оба аннотированы @Inject). Затем вы должны использовать Injector, чтобы получить единственный экземпляр этого третьего объекта. - person condit; 12.02.2013
comment
На практике вы редко видите injector. Например, если вы используете Jersey с Guice, вы настраиваете свои модули, а затем платформа обрабатывает все остальное. - person condit; 12.02.2013
comment
т.е. у Джерси есть поддержка Guice из коробки? Это как: Джерси — это компонент, управляемый Guice, поэтому нам не нужно явно использовать экземпляр Injector? - person MyTitle; 12.02.2013
comment
Или вы имеете в виду Джерси в контексте контейнера JEE? т.е. CDI (Guice) можно использовать только в компонентах контейнерного менеджера, таких как EJB, JAX-RS (Джерси), JAX-WS и т. д. без явного использования Injector#getInstance? - person MyTitle; 12.02.2013
comment
Не из коробки. Вам нужно добавить зависимость к jersey-guice. См. пример здесь: randomizedsort.blogspot.com /2011/05/ и обратите внимание, что Injector не используется. - person condit; 12.02.2013
comment
давайте продолжим это обсуждение в чате - person condit; 13.02.2013