Guice 如何在没有 @Inject 注释的构造函数的情况下注入 类?

How does Guice inject classes without an @Inject-annotated constructor?

我正在尝试了解我们的代码库 (Kotlin) 中如何使用 DI。我们正在使用 google guice 进行依赖注入。

这是一个示例 class:

class ServiceClass @Inject construct(
     private val depA: DepA,
     private val depB: DepB
) { ........ }

在模块 class 中:

@Provides
fun provideDepA(): DepA {
 //constructs DepA object and returns it
}

部门 B class:

class DepB { .... }

据我所知,对于用 @Inject 注释的变量,Google Guice 将寻求使用模块 class 来解决这些依赖关系。所以 DepA 对象是如何注入的是有道理的。

但是 DepB 呢?我们如何能够在不指定任何地方的情况下注入 DepB?

未在模块中声明的 Guice 绑定称为 Just-in-time Bindings,默认情况下 Guice 愿意调用采用零参数的构造函数:

Guice Wiki: JustInTimeBindings

Guice can create bindings for concrete types by using the type's injectable constructor. Guice considers a constructor injectable if:

  • (recommended) The constructor is explicitly annotated with @Inject (both com.google.inject.Inject and javax.inject.Inject are supported).
  • or, the constructor takes zero arguments, and
    • the constructor is non-private and defined in a non-private class (Guice supports private constructor only when it is defined in a private class, however, private constructors are not recommended because they can be slow in Guice due to the cost of reflection).
    • the injector has not opted in to require explicit @Inject constructor, see explicit @Inject constructors section below.

如果你还没有 required explicit bindings and you have a public no-arg constructor, Guice will call it as if you had marked it with @Inject. This is in contrast to Dagger, which will only call @Inject-annotated constructors:

Dagger Dev Guide

If your class has @Inject-annotated fields but no @Inject-annotated constructor, Dagger will inject those fields if requested, but will not create new instances. Add a no-argument constructor with the @Inject annotation to indicate that Dagger may create instances as well.

...

Classes that lack @Inject annotations cannot be constructed by Dagger.

在 Guice 和 Dagger 中,您都可以在 @Provides 方法中自己构造对象,在 Guice 中,您还可以使用 Module 来 explicitly bind to a constructor 带参数但不带 @Inject 构造函数.