Dagger 注入的簡單原理

最簡單的使用步驟:bash

聲明一個 Moduleide

@Module
public class MainModule {

    @Provides
    Dog provideDog(){
        return new Dog("bob");
    }

}
複製代碼

聲明一個 Component 代表要把哪一個 module 注入到哪些對象,以下表示把 MainModule 注入到 MainActivity 對象中,那麼在 MainActivity 中就能夠隨意使用 @Inject 注入 MainModule 中的提供的對象實例。ui

@Component(modules = MainModule.class)
public interface MainComponent {
    void inject(MainActivity mainActivity);
}
複製代碼

而後咱們在 MainActivivty 中使用:this

class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var dog1: Dog

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        DaggerMainComponent.builder().build().inject(this)
        TextView.text = "$dog1"
    }
}
複製代碼

就能夠不須要 new Dog() 而直接獲得一個現成的實例,這背後是怎麼實現的呢?一塊兒來看看。spa

編譯以後,dagger 註解處理器會生成 3 個文件:code

  1. DaggerMainComponent
  2. MainActivity_MembersInjector
  3. MainModule_ProvideDogFactory

上文中咱們注入以前須要在 MainActivity 先初始化一下 DaggerMainComponent.builder().build().inject(this) 注入到當前的類中。對象

DaggerMainComponent 具體實現瞭如何把一個 MainModule 注入到 MainActivity中。get

public final class DaggerMainComponent implements MainComponent {
  private final MainModule mainModule;

  private DaggerMainComponent(MainModule mainModuleParam) {
    this.mainModule = mainModuleParam;
  }

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

  public static MainComponent create() {
    return new Builder().build();
  }

  @Override
  public void inject(MainActivity mainActivity) {
    injectMainActivity(mainActivity);
  }

  private MainActivity injectMainActivity(MainActivity instance) {
    MainActivity_MembersInjector.injectDog1(
        instance, MainModule_ProvideDogFactory.provideDog(mainModule));
    return instance;
  }

  public static final class Builder {
    private MainModule mainModule;

    private Builder() {}

    public Builder mainModule(MainModule mainModule) {
      this.mainModule = Preconditions.checkNotNull(mainModule);
      return this;
    }

    public MainComponent build() {
      if (mainModule == null) {
        this.mainModule = new MainModule();
      }
      return new DaggerMainComponent(mainModule);
    }
  }
}
複製代碼

首先 DaggerMainComponent.Builder 的 build 方法中會先建立一個 MainModule 實例,而後傳入 DaggerMainComponent。string

而後再看看 inject(),內部經過 MainActivity_MembersInjector.injectDog1(MainActivity,Dog) 實現,這裏的 dog 實例是從 MainModule_ProvideDogFactory.provideDog(mainModule) 這個工廠類得到的。it

public final class MainModule_ProvideDogFactory implements Factory<Dog> {
  private final MainModule module;

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

  @Override
  public Dog get() {
    return provideDog(module);
  }

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

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

複製代碼

provideDog() 這個方法很簡單,就是判斷下實例是必須不能爲空。

最後經過 injectDog1()MainActivitydog1 賦值,完成了注入過程。

public static void injectDog1(MainActivity instance, Dog dog1) {
    instance.dog1 = dog1;
  }
複製代碼

這樣一個注入過程就完成了,是否是很簡單。

相關文章
相關標籤/搜索