如何注射注射器?

Ale*_*x M 29 dependency-injection guice

情况:我需要一些延迟依赖实例化FooClass,所以我Injector作为构造函数参数传递给类.

private final Injector m_injector;

public FooClass(@Named("FooInjector") Injector injector) {
m_injector = injector;
}
Run Code Online (Sandbox Code Playgroud)

但是guice不允许绑定核心类(注入器,模块等).解决办法是什么?

gpa*_*ara 27

你不应该Injector直接使用.而是通过Provider<FooClass>相反.此外,您应该在您使用的地方注入提供程序FooClass.

private final Provider<FooClass> provider;

@Inject
public ClassWhereFooIsUsed(Provider<FooClass> provider) {
    this.provider = provider;
}

.... somewhere else
FooClass f = provider.get(); // This is lazy
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`@Inject Injector injector`获取进样器,可以在构造函数/ field /方法上. (8认同)
  • @AlexM:如果你真的需要的话,看看`childInjectors`.一般来说,它们不应该被需要,你应该只使用一个注射器.有例外,但很少见. (2认同)
  • 为什么需要多个注射器?我真的无法想象. (2认同)

Dav*_*oha 13

正如其他人已经回答的那样,你可以简单地使用,@Inject Injector因为Guice定义了绑定本身.

通常Injector,您的应用程序中只需要一个,静态变量是一种更容易存储和访问单例的方法,而不是注入它.在我们的Web应用程序中,我们使用stripe-guicer并在需要时Injector从其静态方法获取GuiceInjectorFactory.getInjector()(例如,在我们的Hibernate拦截器中).

我对"你不应该直接使用注射器"的建议感到有些困惑.除了通过调用injector.getInstance()injector.injectMembers()?之外,我还能如何注入实例?没有办法.是的,您可以定义Provider方法,但除非在某处,某些东西使用Injector,否则它们永远不会被调用.是的,有些模块使用Injector你喜欢的ServletModule ; 你必须创造Injector自己,但你可以留在那ServletModule之后.

因此在某些情况下,您可以避免Injector直接使用,但这并不意味着您"不应该"使用它.如果您在没有任何可选模块的情况下单独使用Guice,那么您"应该" Injector在整个地方使用,因为没有其他方法可以触发注入.(我认为花费一整天在框架内编写代码的开发人员有时会忘记某些人实际上是在实例化他们自己的对象.)

  • 我唯一的观点(我所做的相当冗长)是你必须从某个地方开始; 这是鸡与蛋的问题.你不能*只*用@Inject来装饰方法,并期望发生任何事情.某个地方必须调用injector.getInstance()或者injector.injectMembers()来启动它. (14认同)
  • 我不相信你已经理解了Guice背后的理由.它明确地旨在避免使用静态字段和状态,并且您应该很少直接引用Injector本身.通过使用@Inject声明依赖项来获取实例,而不是在注入器上调用`getInstance()`. (3认同)
  • 与其说“你不应该直接使用`Injector`”,不如说“你不应该*注入*`Injector`”。Guice 提供了很多对模块创建的检查,如果模块*内部*的东西最终自己注入了一个“Injector”,那么这些检查都不起作用。最初从“Guice.createInjector(...myModules)”手动创建的“Injector”非常好用。 (3认同)

Col*_*inD 8

正如@gpampara所说,Provider<T>应该用于惰性/可选的初始化.另外,正如我在回答您的其他问题时所说的那样Injector,几乎在所有情况下都应避免引用代码中的内容.

也就是说,在由Guice创建的类中,Injector只需通过声明依赖项就可以注入创建对象Injector.在Injector自动供注射没有你声明的任何约束力.

如果你注射了它Injector,你应该考虑为什么要这样做.为什么不直接声明类所依赖的实际接口/类的依赖?向构造函数添加新的依赖项同样容易,因为它通过Injector代码中的其他地方检索某个依赖项的实例,并且使代码更容易理解.