Kotlin 目标模块中的Dagger@Singleton

Kotlin 目标模块中的Dagger@Singleton,kotlin,dagger-2,Kotlin,Dagger 2,我有一个问题,使用@Module对象而不使用@Singleton函数与使用@Singleton函数的@Module类之间是否存在显著差异 就像: @Module object ApiModule { @Provides fun test() } 是否必须在对象中标记@Singleton?是如果没有@Singleton,则每次需要注入测试返回的内容时,都会调用该函数一次。如果您有@Singleton,则返回值将由dagger缓存,并在每次需要时重新使用。由于dagger是一个注

我有一个问题,使用
@Module
对象而不使用
@Singleton
函数与使用
@Singleton
函数的
@Module
类之间是否存在显著差异

就像:

@Module
object ApiModule {

    @Provides
    fun test()
}

是否必须在
对象
中标记
@Singleton

是如果没有@Singleton,则每次需要注入测试返回的内容时,都会调用该函数一次。如果您有@Singleton,则返回值将由dagger缓存,并在每次需要时重新使用。

由于dagger是一个注释处理器,通常最简单和最简单的解决方案是只查看生成的代码

我准备了一个最低限度的样本来证明:

class Foo()
class Bar()

@Component(modules = [ClassModule::class, ObjectModule::class])
interface FooComponent {

    val foo: Foo
    val bar: Bar
}

@Module
class ClassModule {

    @Provides
    fun foo() = Foo()
}

@Module
object ObjectModule {

    @Provides
    fun bar() = Bar()
}
如果我们看一下生成的代码,我们可以看到以下内容(我删除了一些不相关的部分,只需自己编译上面的代码,如果您想查看全部内容,请查看实现)

您会注意到,Dagger为
ClassModule
创建了一个对象,但直接使用了
ObjectModule
及其静态方法。这有关系吗?嗯,创建一个新对象很慢,这并不重要,但我们也不需要不必要地降低性能。因此,如果可以的话,您应该明确地选择
对象
接口
作为模块,以获得更好的性能

至于作用域,模块的外观并不重要,重要的是方法签名。Dagger查看方法的返回类型及其任何注释。因此,是的,当然您需要设置一个范围,无论您对模块使用什么,
对象
,或
接口
。理想情况下,您应该在类本身上添加作用域,并使用构造函数注入来完全避免模块



tl;dr
模块会导致创建一个额外的对象,因此如果可能的话,应首选
接口
对象
模块。

非常清晰且令人敬畏的回答。感谢您的时间和努力:)
class Foo()
class Bar()

@Component(modules = [ClassModule::class, ObjectModule::class])
interface FooComponent {

    val foo: Foo
    val bar: Bar
}

@Module
class ClassModule {

    @Provides
    fun foo() = Foo()
}

@Module
object ObjectModule {

    @Provides
    fun bar() = Bar()
}
public final class DaggerFooComponent implements FooComponent {
  private final ClassModule classModule;

  private DaggerFooComponent(ClassModule classModuleParam) {
    this.classModule = classModuleParam;
  }

  public static Builder builder() {
    return new Builder();
  }

  @Override
  public Foo getFoo() {
    return ClassModule_FooFactory.foo(classModule);}

  @Override
  public Bar getBar() {
    return ObjectModule_BarFactory.bar();}

  public static final class Builder {
    private ClassModule classModule;

    private Builder() {
    }

    public Builder classModule(ClassModule classModule) {
      this.classModule = Preconditions.checkNotNull(classModule);
      return this;
    }

    public FooComponent build() {
      if (classModule == null) {
        this.classModule = new ClassModule();
      }
      return new DaggerFooComponent(classModule);
    }
  }
}