结合@Provides和@Inject

Ora*_*le3 2 guice

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

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

Jef*_*ica 10

不,从来没有一种情况,你会看到@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.
  }
}
Run Code Online (Sandbox Code Playgroud)

@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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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