目錄
一: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的注入原理,更加水到渠成。