provides nfl google derrius dependency java dependency-injection guice

java - nfl - ¿Accediendo al inyector de Guice en su módulo?



guice vs spring (1)

Estoy extendiendo el Módulo AbstractModule de Guice y dentro de la clase extendida necesito acceso al inyector de Guice. Es posible, si es así, ¿cómo?


Esta es una petición inusual. Los módulos se parecen más a los archivos de configuración que a los archivos lógicos: el módulo se lee para crear el inyector y, en cuanto se crea el inyector, el módulo ha hecho su trabajo. Para un módulo simple, el inyector literalmente no existe hasta que el módulo esté listo para ser desechado.

En cualquier caso, en lugar de solicitar un Inyector para obtener la clase X, normalmente debe solicitar un Provider<X> . Guice inyectará una X o Provider<X> para cualquier enlace de X , Provider<X> o @Provides X , por lo que casi siempre puede hacer esto en su lugar. Dicho esto, inyectar el inyector le permitirá obtener una instancia de manera reflexiva o inspeccionar los enlaces del inyector (etc.).

Aquí hay algunas razones / diseños válidos que requerirían acceder a un inyector desde un módulo:

En un método @Provides :

Los módulos pueden contener mini-proveedores en métodos anotados con @Provides . Recuerde que el Injector es inyectable : si necesita un inyector en uno de esos métodos, simplemente puede aceptarlo como un parámetro:

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<Thing> thingProvider) { return new SomethingElse(thingProvider); // asking for a provider works too } }

Para obtener un proveedor en su configuración ():

AbstractModules expone getProvider() exactamente por este motivo, aunque obtendrá un error si llama a get() en ese Proveedor antes de que el inyector esté listo para proporcionarlo (como en el momento de la configuración):

public class TwoModule extends AbstractModule { @Override public void configure() { bind(Thingy.class).toInstance( new MyThingy(8675309, getProvider(Another.class))); } }

Probablemente puedas llamar a getProvider(Injector.class) pero no sé si eso funciona y no sé por qué querrías hacerlo.

Para obtener una instancia en su configure ():

Esta es una mala idea; Guice no está listo para proporcionar instancias hasta que se hayan ejecutado todos los métodos de configuración. Lo más cercano que puede acercarse es crear un inyector secundario usando los otros módulos y pasarlo a este módulo, pero incluso eso rara vez es necesario.

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); } }