Доступ к инжектору Guice в его модуле?
Я расширяю AbstractModule
Guice и внутри расширяющегося classа, мне нужен доступ к инжектору Гиса. Это возможно, если да, то как?
- Модульный ввод / вывод файлов
- «Взаимозависимость» (DI) «дружественная» библиотека
- ContextLoaderListener или нет?
- Как я могу вводить в @FacesConverter?
- Включение зависимостей со статическим регистратором, статическим вспомогательным classом
- Шаблон страtagsи и зависимость от использования с помощью Unity
- Использование инъекции зависимостей без какой-либо библиотеки DI
- Регистрация фаз (прототип) во время выполнения весной
Это необычный запрос. Модули больше похожи на файлы конфигурации, чем на логические файлы. Модуль читается для создания Инжектора, а затем, как только инжектор создается, модуль выполнил свою работу. Для простого модуля инжектор буквально не существует, пока модуль не будет готов к отбрасыванию.
В любом случае, вместо того, чтобы запрашивать инжектор для получения classа X, вы обычно должны запрашивать Provider
. Guice будет вводить X
или Provider
для любой привязки X
, Provider
или @Provides X
, поэтому вы можете почти всегда делать это вместо этого. Тем не менее, инъекция инжектора позволит вам получить экземпляр рефлексивно или проверить привязки Инъектора (и т. Д.).
Вот несколько веских причин / конструкций, которые требуют доступа к инжектору из модуля:
В методе @Provides
:
Модули могут содержать мини-провайдеров в методах, аннотированных с помощью @Provides
. Помните, что Injector
инъектируется : если вам нужен инжектор в одном из этих методов, вы можете просто принять его как параметр:
public class OneModule extends AbstractModule { @Override public void configure() { /* ... */ } @Provides YourDependency getYourDependency(Injector injector) { return injector.getInstance(Class.forName(yourDependencyName)); } @Provides Something getSomething(SomethingImpl something) { return initialize(something); // preferred: only ask for what you need } @Provides SomethingElse getSomethingElse(Provider thingProvider) { return new SomethingElse(thingProvider); // asking for a provider works too } }
Чтобы получить Провайдера в вашем configure ():
AbstractModules раскрывают getProvider()
именно по этой причине, хотя вы получите сообщение об ошибке, если вы вызываете get()
в этом Провайдере, прежде чем инжектор будет готов его предоставить (например, во время настройки):
public class TwoModule extends AbstractModule { @Override public void configure() { bind(Thingy.class).toInstance( new MyThingy(8675309, getProvider(Another.class))); } }
Вероятно, вы можете вызвать getProvider(Injector.class)
но я не знаю, работает ли это, и я не знаю, зачем вам это нужно.
Чтобы получить экземпляр в configure ():
Это плохая идея; Guice не готов предоставлять экземпляры до тех пор, пока не будут запущены все методы настройки. Самое близкое, что вы можете получить, это создать дочерний инжектор, используя другие модули, и передать его в этот модуль, но даже это редко необходимо.
public class MainClass { public static void main(String[] args) { Injector firstStage = Guice.createInjector(new OtherModule1(), new OtherModule2()); // An alternative design would @Inject-annotate fields in ThreeModule // and get it from firstStage, but that's nonstandard and may be confusing. Injector secondStage = firstStage.createChildInjector(new ThreeModule(firstStage)); } } public class ThreeModule extends AbstractModule { private final Injector otherInjector; public ThreeModule(Injector otherInjector) { this.otherInjector = otherInjector; } @Override public void configure() { bindStuffBasedOn(otherInjector); } }