Dagger2利器系列三:原理、用途

目錄

一:dagger2的好處or用途

1.1 一切都是爲了解耦

1.2 增加開發效率

1.3 更好的管理類實例

二 原理分析

參考文章:


一:dagger2的好處or用途

1.1 一切都是爲了解耦

一切都是爲了解耦。

一個類的new代碼是非常可能充斥在app的多個類中的,假如該類的構造函數發生變化,那這些涉及到的類都得進行修改。設計模式中提倡把容易變化的部分封裝起來。

我們用了dagger2後,假如是通過用Inject註解標註的構造函數創建類實例,則即使構造函數變的天花亂墜,我們基本上都不需要修改任何代碼。假如是通過工廠模式Module創建類實例,Module其實就是把new類實例的代碼封裝起來,這樣即使類的構造函數發生變化,只需要修改Module即可。

我認爲如果是小app一般沒必要用到Daggger2(爲了學習還是好的),解耦也是要付出相應的空間和時間代價的,工作量和複雜度都可能會提高(多人協作大項目會提高你的效率),編譯時也容易出錯,但在解耦數據和業務邏輯方面,Dagger2無愧利器之名。

1.2 增加開發效率

這裏的開發效率着重於:省去重複而又無意義new實例對象代碼。當然這也會增加我們一些依賴包括module、component等代碼的鋪墊,但做完這些鋪墊,dagger2就可以把new一個實例的工作做了,從而讓開發者把精力集中在業務上。

一個很棒的例子就是Dagger2中單例的寫法,開發者不需要擔心自己寫的單例方法是否線程安全,懶漢or餓漢模式,這些Dagger2都會幫你搞定。

1.3 更好的管理類實例

每個app中的ApplicationComponent管理整個app的全局類實例,所有的全局類實例都統一交給ApplicationComponent管理,並且它們的生命週期與app的生命週期一樣。
每個頁面對應自己的Component,頁面Component管理着自己頁面所依賴的所有類實例。因爲Component,Module,整個app的類實例結構變的很清晰。


二 原理分析

在大體介紹完 Dagger2 後,我們分析一下實現原理。

《Dagger2利器系列一:入門到使用》中最簡單的 案例A:入門demo爲例,Dagger2 在編譯時根據註解生成一些輔助類,我們具體分析下生成的輔助類。輔助類可以通過 DaggerXXXComponent 來快速定位。上面兩個例子對應生成輔助類如下:

我們分析下具體的注入過程,首先 Car 中會調用DaggerCarComponent.builder().build().inject(this);,我們來看下 DaggerCarComponent 的源碼:

public final class DaggerCarComponent implements CarComponent {
  private DaggerCarComponent() {

  }

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

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

  @Override
  public void inject(Car car) {
    injectCar(car);}

  private Car injectCar(Car instance) {
    Car_MembersInjector.injectEngine(instance, new Engine());
    return instance;
  }

  public static final class Builder {
    private Builder() {
    }

    public CarComponent build() {
      return new DaggerCarComponent();
    }
  }
}

可以看到,DaggerCarComponent 是CarComponent的實現類,最終調用到了inject方法裏的injectCar方法,然後調用了injectCar方法裏的 Car_MembersInjector.injectEngine(instance, new Engine());

我們來看下Car_MembersInjector的源碼:

public final class Car_MembersInjector implements MembersInjector<Car> {
  private final Provider<Engine> engineProvider;

  public Car_MembersInjector(Provider<Engine> engineProvider) {
    this.engineProvider = engineProvider;
  }

  public static MembersInjector<Car> create(Provider<Engine> engineProvider) {
    return new Car_MembersInjector(engineProvider);}

  @Override
  public void injectMembers(Car instance) {
    injectEngine(instance, engineProvider.get());
  }

  @InjectedFieldSignature("com.ysalliance.getfan.daggertest.Car.engine")
  public static void injectEngine(Car instance, Engine engine) {
    instance.engine = engine;
  }
}

可以看到,這是Car對應的@Inject。

Engine_Factory對應的源碼:

public final class Engine_Factory implements Factory<Engine> {
  @Override
  public Engine get() {
    return newInstance();
  }

  public static Engine_Factory create() {
    return InstanceHolder.INSTANCE;
  }

  public static Engine newInstance() {
    return new Engine();
  }

  private static final class InstanceHolder {
    private static final Engine_Factory INSTANCE = new Engine_Factory();
  }
}

可以看到,Engine_Factory,是Engine構造方法的@Inject。

 

上面是最簡單的Dagger2的注入原理的分析,如果想看帶@Module 和 @Provides的稍微複雜一點的Dagger2的注入原理,推薦看這一篇博文:《Dagger2 使用及原理分析》,相信在這篇的基礎上,學習帶@Module 和 @Provides的注入原理,更加水到渠成。

 

 

參考文章:

dagger2到底有哪些好處?

關於Android Dagger2 應用的疑惑?

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