android Dagger2 @Module和@Provides 依赖注入

通过@Inject提供对象来依赖注入有以下两个缺点

  • 如果要注入的对象属于某个第三方库中的类,那么我们是无法在在这个类的构造方法上添加@Inject注解的
  • 如果要注入的对象是个abstract抽象类或者Interface接口,那么这个类似没有构造方法的,也无法添加@Inject注解

要解决以上问题,这时候就需要@Module和@Provides这对好基友上场了

二话不说,直接上代码

public interface Person {
    String saySomething();
}
public class Student implements Person {

    public String name;

    // 这边不需要再用@Inject了
    public Student() {
        this.name = "野猿新一";
    }

    @Override
    public String toString() {
        return String.format("我的名字叫%s啦", name);
    }

    @Override
    public String saySomething() {
        return toString();
    }
}
@Module
public class MainModule {
    // 注意返回类型要明确是Person,而不能是子类Student
    // 这里我们就能够提供了一个接口的实例了
    @Provides
    public Person providePerson() {
        return new Student();
    }
}
// 这里记得加载module
@Component(modules = MainModule.class)
public interface MainActivityComponent {
    void inject(MainActivity activity);
}
public class MainActivity extends AppCompatActivity {

    // 这里声明的是一个接口
    @Inject
    Person person;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerMainActivityComponent.create().inject(this);
        TextView textView = findViewById(R.id.text);
        textView.setText(person.saySomething());
    }
}

运行结果,成功注入了Person对象

生成代码解析

Dagger为我们生成了很多代码,我们看下注入的流程

DaggerMainActivityComponent和MainActivity_MemberInjector在前面的文章中已经有介绍就不黏贴了

我们这次主要看下跟@Module和@Provides有关的MainModule_ProvidePersonFactory的代码,代码很简单,通过module来提供注入的对象

public final class MainModule_ProvidePersonFactory implements Factory<Person> {
  private final MainModule module;

  public MainModule_ProvidePersonFactory(MainModule module) {
    this.module = module;
  }

  @Override
  public Person get() {
    return provideInstance(module);
  }

  public static Person provideInstance(MainModule module) {
    return proxyProvidePerson(module);
  }

  public static MainModule_ProvidePersonFactory create(MainModule module) {
    return new MainModule_ProvidePersonFactory(module);
  }

  public static Person proxyProvidePerson(MainModule instance) {
    return Preconditions.checkNotNull(
        instance.providePerson(), "Cannot return null from a non-@Nullable @Provides method");
  }
}

我们再看下整个的注入流程的代码

DaggerMainActivityComponent.create().inject(this);

 DaggerMainActivityComponent中的相关代码

DaggerMainActivityComponent内部的建造器,Module在这里生成

public static final class Builder {
  private MainModule mainModule;

  private Builder() {}

  public MainActivityComponent build() {
    if (mainModule == null) {
      this.mainModule = new MainModule();
    }
    return new DaggerMainActivityComponent(this);
  }

  public Builder mainModule(MainModule mainModule) {
    this.mainModule = Preconditions.checkNotNull(mainModule);
    return this;
  }
}
@Override
public void inject(MainActivity activity) {
  injectMainActivity(activity);
}

@CanIgnoreReturnValue
private MainActivity injectMainActivity(MainActivity instance) {
  MainActivity_MembersInjector.injectPerson(
      instance, MainModule_ProvidePersonFactory.proxyProvidePerson(mainModule));
  return instance;
}

 MainModule_ProvidePersonFactory中的proxyProvidePerson()方法,返回由module提供的Person对象

public static Person proxyProvidePerson(MainModule instance) {
  return Preconditions.checkNotNull(
      instance.providePerson(), "Cannot return null from a non-@Nullable @Provides method");
}

MainActivity_MembersInjector中的injectPerson()方法,将提供的Person对象赋值给Activity的person成员变量,完成注入

public static void injectPerson(MainActivity instance, Person person) {
  instance.person = person;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章