匕首2-场注入中的空指针

时间:2018-11-14 18:11:27

标签: java dependency-injection dagger-2 dagger

我使用匕首2进行依赖项注入,并被现场注入卡住了。下面是带有代码示例的完整方案:

假设我们有一个类A,它依赖于库B

class A {
    @Inject
    B b;
}

B的模块:

@Module
public class BModule {

    @Provides
    @Singleton
    public B provideB() {
        return new C.methodA();
        // C - static class; C.methodA returns B

    }
}

但是当我尝试在A类中使用b时,我会得到空指针异常,但是如果我使用构造函数注入进行了同样的操作,则它会完美地工作。 我可以确保组件和其他依赖项都可以正常使用,因为构造器部分可以正常工作。

A是某个其他类的依赖项(让我们称之为X),并且正在使用构造函数注入(已测试)来初始化A。另外,X被注入为void inject(X x);

我有2个问题:

  1. 由于没有被注入,我有什么需要错过的吗?
  2. 我能够成功地编译代码并获得运行时异常,但是dagger2是编译时DI,那么为什么在编译时却无法捕捉到这一点?

P.S .:由于存在多个依赖关系,我刚刚共享了部分代码,因此请尝试解释这种情况。让我知道问题/场景是否仍然不清楚或需要更多信息。

谢谢。

1 个答案:

答案 0 :(得分:1)

dagger中的字段注入比构造函数注入更加复杂。当您使用这样的构造函数注入

class A {
    @Inject
    public A(B b) {}
}

并且您有B类的提供者

@Module
class DaggerModule {
    @Provides
    B provideB() {}
}

现在,匕首将知道如何创建A的实例并将其传递给必需的构造函数参数。因此一切都很好,可以成功编译并且可以完美运行。

但是如果我们谈论场注入

class A {
    @Inject
    B b;
}

,并且在某个地方提供了B的提供者,匕首不知道如何创建A实例以及何时注入b属性(在手动创建A实例的情况下)用手)。要使其正常工作,您需要在组件中编写特殊的方法

@Component(DaggetModule.class)
interface DaggerComponent {
    void inject(A a);
}

以及代码中的某处

A a = new A();
DaggerComponent component = //TODO getDaggerComponent()
component.inject(a);

此后,b属性将被初始化并可供以后使用。希望,现在很清楚如何使场注入工作。