Я знаю, что обычно инжектор должен использоваться только один раз во всех приложениях (при запуске). Но у меня есть следующий прецедент. Я внедряю задачу выполнения для Executor, а затем внутри этой задачи у меня есть зависимость (скажем, FileHandler
), которая должна создаваться каждый раз. Я знаю, что нужно внедрить провайдера (скажем FileHandlerProvider
), который будет возвращать новый экземпляр каждый раз по запросу. Проблема в том, что FileHandler
имеет множество собственных зависимостей (скажем Parser
, OutputPrinter
...). Теперь им также нужен новый экземпляр каждый раз (потому что реализация может иметь какое-то состояние, например счетчики, и при следующем запуске повторного использования одного и того же экземпляра). Дело в том, что после того, как провайдер вводится, тот же экземпляр провайдера повторно используется, поэтому новый FileHandler
всегда создается с такими же Parser
и OuputPrinter
. Решение могло бы снова ввести ParserProvider
и OutputPrinterProvider
вместо Parser и OuputPrinter
в FileHandlerProvider
, но это не так, скоро становится слишком сложно, потому что есть больше зависимостей. Единственным простым решением, которое я вижу сейчас, может быть использование Injector в FileHandlerProvider
, который вернет новый экземпляр FileHandler
(и новые экземпляры зависимостей). Или, может быть, в этой ситуации есть еще одно элегантное решение?Guice: инжектор в провайдере
ответ
Вы должны просто привязать FileHandler
и его зависимостями по умолчанию (т. Е. Без области видимости). Затем введите Provider<FileHandler>
и используйте его get()
каждый раз, когда вам нужен новый экземпляр FileHandler
. Поскольку FileHandler
не имеет области видимости, каждый раз, когда get()
называется новым экземпляром FileHandler
, необходимо создать ... и поскольку его зависимости также не имеют области видимости, каждый экземпляр каждого из них должен быть создан каждый раз. Он должен работать так, как вы хотите.
Я думаю, что вещь, в которой вы (возможно) отсутствует здесь, заключается в том, что вам не нужно писать ни одного из этих поставщиков самостоятельно ... просто введите Provider<FileHandler>
, и Guice сделает все это за вас.
Редактировать: Вот небольшой класс, который я написал, который демонстрирует зависимости класса, создаваемого новым, каждый раз, когда создается экземпляр этого класса.
public class Test {
public static void main(String[] args) {
Injector injector = Guice.createInjector();
injector.getInstance(Test.class);
}
@Inject public Test(Provider<FileHandler> fileHandlerProvider) {
FileHandler fileHandler1 = fileHandlerProvider.get();
FileHandler fileHandler2 = fileHandlerProvider.get();
System.out.println("fileHandler1 == fileHandler2? " +
(fileHandler1 == fileHandler2));
System.out.println("fileHandler1.parser == fileHandler2.parser? " +
(fileHandler1.parser == fileHandler2.parser));
System.out.println("fileHandler1.print == fileHandler2.printer? " +
(fileHandler1.printer == fileHandler2.printer));
}
private static class FileHandler {
private final Parser parser;
private final OutputPrinter printer;
@Inject private FileHandler(Parser parser, OutputPrinter printer) {
this.parser = parser;
this.printer = printer;
}
}
private static class Parser {
}
private static class OutputPrinter {
}
}
При запуске этот код печатает:
fileHandler1 == fileHandler2? false fileHandler1.parser == fileHandler2.parser? false fileHandler1.print == fileHandler2.printer? false
Это показывает, что не только новый FileHandler
экземпляр создается каждый раз, новые Parser
и OutputPrinter
экземпляры были создавать и впрыскивается в к FileHandler
каждый раз также.
- 1. Guice: использовать инжектор?
- 2. Как использовать инжектор Guice?
- 3. Не удается запустить Guice Repository Инжектор
- 4. Как я получаю контекст с guice в провайдере?
- 5. Есть ли эквивалент Guice Providers в простой инжектор?
- 6. Отказоустойчивый инжектор для дочерних модулей. Дополнительные привязок в Google Guice
- 7. Guice инъекционный инжектор или общий провайдер каким-то образом
- 8. Как заставить Джексона использовать инжектор Google Guice для создания экземпляров?
- 9. Гибкий инжектор внутри резьбы
- 10. Зависимость впрыска в Guice
- 11. Недопустимые дети в Провайдере
- 12. Как использовать гик-инжектор в качестве провайдера?
- 13. [$ Инжектор: nomod], [$ Инжектор: modulerr] Ошибка в Угловое
- 14. Угловой 1: $ инжектор не может найти зависимость поставщика при инъекционном провайдере внутри провайдера
- 15. Комбинируя Guice и JAXB
- 16. Файлы Guice и свойств
- 17. Ускорить инжектор с несколькими AbstractGinModule
- 18. Давать значение Provider в Guice
- 19. bootstrapping guice injector
- 20. Guice: Как создать HttpSessionProvider
- 21. исключение интеграции Guice Guice
- 22. Глобальные инжекторы с Guice
- 23. Larvel5: Аутентифицированный пользователь в Провайдере
- 24. Угловая инъекция $ rootScope в провайдере
- 25. Получить членство в провайдере Имя
- 26. Ошибка произошла в HibernatePersistence провайдере
- 27. Утерян на членском провайдере
- 28. Как создать родительский инжектор Guice в основном с помощью RESTEasy и встроенного причала
- 29. Guice: последствия инъекции поля
- 30. Угловая ошибка [$ Инжектор: modulerr] - инжектор nomod
Привет, спасибо за ответ, но дело в том, что даже если я не создаю поставщиков вручную - зависимости FileHandler - это те же повторные экземпляры. Вероятно, это происходит из-за того, что Task создается только один раз, затем он вводит провайдера (также только один экземпляр), поставщик создает новый экземпляр FileHandler, но всегда использует те же экземпляры зависимостей FileHandler, поскольку они были введены в провайдер по указанию на его создание. Так что я не хочу, чтобы другого выхода не было, просто используйте инжектор в провайдере ... – nesvarbu
@ Игнас: Я не уверен, что вы имеете в виду. Зависимости не следует использовать повторно, если они не имеют какой-либо области, которая заставляет их повторно использовать или вы делаете то, что специально заставляет их повторно использовать. См. Мой пример, демонстрирующий это. – ColinD
Эй, это была моя ошибка, когда я отлаживал. Это работает. Благодаря! :) – nesvarbu