如果在@Provides方法中将Injector作为参数传递,会发生什么情况

时间:2018-12-21 01:35:02

标签: dependency-injection guice

我在以下项目中看到了几种用法(我正在发布代码的本质,因此更易于阅读):

public static void main(Strings[] args) {
    Injector i = Guice.createInjector(new MyModule());
    i.getInstance(Foo.class);
}

class Foo {}

class MyModule extends AbstractModule {
    @Provides
    public Foo getFoo(Injector injector) {
        return new Foo();
    }
}

当我尝试在模块中打印injector.toString()时,我认为Guice以某种方式将Injector绑定到实例i本身。

例如

public static void main(Strings[] args) {
    Injector i = Guice.createInjector(new MyModule());
    Injector j = i.getInstance(Injector.class);
    if (i == j) {
        // true
    }
}
....

因此,在这种情况下,是否可以有人阐明Guice如何通过getFoo(injector)方法获取Injector实例?谢谢!

1 个答案:

答案 0 :(得分:1)

Injector可在您的图形中注入,并且Guice将为@Provides方法提供参数。但是,您只需要在极少数情况下注入Injector,并且如果不使用Injector则不需要请求。


@Provides
public Foo getFoo(Dep1 dep1, Dep2 dep2) {
    return new Foo(dep1, dep2);
}

这假定Guice可以创建Dep1和Dep2的实例(通过构造函数,绑定或@Provides方法),并且与在Foo中注释了构造函数大致相同。 Guice在调用Foo构造函数时将注入Dep1和Dep2的实例,而Guice在调用上述@Provides Foo getFoo方法时将提供实例。

@Inject public Foo(Dep1 dep1, Dep2 dep2) { /* ... */ }

如您所链接的Injector类的文档中所述(latest docs available here):

  

包含几个默认绑定:

     
      
  • Injector实例本身
  •   
  • 每个Provider<T>类型的绑定为T
  •   
  • 正在注入的课程的Logger
  •   
  • 创建了注射器的Stage
  •   

因此,您可以将Dep1,Dep2,Provider,Provider,Injector或Provider<Injector>放入您的@Provides方法参数或@Inject构造函数参数(或@Inject字段中,等等)。在内部,Injector支持在InjectorShell.java中作为一种特殊情况发生,因为父级和子级Injector会返回不同的Injector实例,作为Guice关于具有相同绑定的父级和子级规则的例外。


您为什么要注入一个注入器?为了阅读和测试,通常最好注入您需要的依赖项(例如Dep1)或其提供者(例如{{1} }。仅在需要将其传递到其他对象中时才需要注入该注入器,例如您已经适应使用Guice注入器的旧式服务定位器,或者需要反射性使用via Guice's SPIto get an instance based on a Class object。这些很少见,并且在大多数类或Provider<Dep1>方法中不一定是必需的。

@Provides

另请参阅:Accessing Guice injector in its Module?