结合@Provides和@Inject

时间:2017-06-17 07:05:34

标签: guice

我最近遇到了一些在同一方法上同时使用@Provides@Inject注释的代码。此方法有两个非基本参数和一个非void返回类型。

我想知道将这两者结合使用是否合理。从我可以收集/推测的内容来看,似乎@Inject用于使用Guice构造方法依赖项,而@Provides用于绑定返回类型。任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:7)

不,绝不会在同一方法上看到@Provides@Inject

@Inject构造函数,方法和字段有意义:

  • 在构造函数上,它标记了DI框架应该调用的构造函数。框架提供所有参数值。
  • 在字段上,表示DI框架应从外部设置字段。框架提供了字段值。
  • 在方法上,它表明在构造之后,DI框架应该只调用方法一次。框架提供参数值。返回值没有意义,通常为void

例如:

public class YourInjectableClass {

  // Guice will use this constructor...
  @Inject public YourInjectableClass(YourDep dep) { /* ... */ }
  // ...instead of this one
  public YourInjectableClass(YourDep dep, YourOtherDep otherDep) { /* ... */ }

  // Guice will populate this field after construction.
  @Inject YourField yourField;

  @Inject public void register(Registry registry) {
    // Guice will create or get a Registry and call this method after construction.
    // It sometimes makes sense for this to be protected or package-private,
    // so this class's consumers aren't tempted to call it themselves.
  }
}

@Provides有一个更窄的目的:当在Guice模块中使用时,@Provides继续使用方法并指示Guice应该在需要方法实例的时候调用该方法 - 可能 - 参数化类型(并从方法本身继承绑定注释或限定符)。 Dagger有一个类似的注释,因为@Provides没有在JSR-330依赖注入标准中定义。

public class YourModule extends AbstractModule {
  @Override public void configure() {)  // still needed for AbstractModule

  // Guice will call this whenever it needs a @SomeBindingAnnotation YourInstance.
  // Because you list a YourDep as a parameter, Guice will get and pass in a YourDep.
  @Provides @SomeBindingAnnotation YourInstance create(YourDep dep) {
    return YourInstanceFactory.create(dep);
  }
}

因此,你几乎不会在同一个文件中看到那些注释,更不用说同一个方法了。唯一的例外是如果你遵循一个可疑的做法,即制作一个本身可注射的模块(可能是从一个注射器获得注射模块以配置不同的注射器),即便如此,你也不会在同一个注射器上看到它们方法:@Inject方法被调用一次以存储依赖项,并且只要需要新实例就应该调用@Provides方法。