溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Dagger學(xué)習(xí) -- 基礎(chǔ)概念

發(fā)布時(shí)間:2020-07-13 15:06:09 來源:網(wǎng)絡(luò) 閱讀:1571 作者:Jinux111 欄目:移動開發(fā)

目標(biāo)

了解 Dagger 基本概念

官方定義

Google 對 Dagger 的定義如下:

Dagger is a fully static, compile-time dependency injection framework for both Java and Android. It is an adaptation of an earlier version created by Square and now maintained by Google.

Dagger 是一個為 Java 和 Android 設(shè)計(jì)的完全靜態(tài),編譯時(shí)依賴注入框架?,F(xiàn)在由 Google 維護(hù),它對 Square 開發(fā)的早期版本進(jìn)行了改寫。

什么是編譯時(shí)依賴呢?就是不在運(yùn)行時(shí)依賴,額...Dagger 會通過注解,生成代碼,而這個代碼跟我們手動寫的依賴注入的代碼一樣。

如果你對『依賴注入』不了解,請看[這篇文章]()(未填的坑)。

Dagger1.x已經(jīng)廢棄,我們以后所說的Dagger就是Dagger2.x。

Dagger 基本概念

Dagger 使用了注解,我們先來最基本的注解的用法。

聲明依賴 @Inject

Dagger 使用注解 javax.inject.Inject 來修飾一個類的構(gòu)造函數(shù),然后就 Dagger 就可以管理它了。當(dāng) Dagger 需要 該類的實(shí)例時(shí),就會調(diào)用這個構(gòu)造函數(shù)來構(gòu)造它,也會自動實(shí)例化該構(gòu)造函數(shù)的參數(shù)所需要的實(shí)例。

@Inject 也可以修飾一個類的屬性,在構(gòu)造這個類時(shí),Dagger 會將這個屬性所需要的對象實(shí)例化出來。但是要注意,這個屬性的類型構(gòu)造函數(shù)需要注入即也用 @Inject 修飾。

@Inject 還可以修飾一個方法,這樣在構(gòu)造實(shí)例后,會立刻調(diào)用該方法。并不推薦這樣做,因?yàn)檫@就是初始化的工作嘛,都可以在構(gòu)造函數(shù)里做。

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  ...
}

class CoffeeMaker {
  @Inject Heater heater;
  @Inject Pump pump;

  ...
}

但是 @Inject 有他的局限性

  1. 接口不能注入,它沒有構(gòu)造函數(shù)。而一個好的設(shè)計(jì)是面向接口編程
  2. 第三方類庫的類,我們不能修改,沒法給它加 @Inject
  3. 我們需要的對象可能需要配置,而且每次需要的配置可能還不同

滿足依賴 @Provides

以上 @Inject 的問題都可以通過 @Provides 來解決。 @Provides 修飾一個方法,這個方法會提供一個對象,在方法里我們自己實(shí)現(xiàn)如何實(shí)例化一個對象,如何配置。這個方法也可以有參數(shù),同 @Inject 修飾的構(gòu)造函數(shù),參數(shù)會被注入。

但是,@Inject 修飾的方法只能是一個 Module 的方法可以是靜態(tài)的或者非靜態(tài)的。而這個 Module 實(shí)際只是一個由 @Module 修飾的普通的類。

約定,@Provides 修飾的方法命名以 provide 開頭,@Module 修飾的類以 Module 結(jié)尾。

@Module
class DripCoffeeModule {
@Provides static Heater provideHeater() {
return new ElectricHeater();
}

@Provides static Pump providePump(Thermosiphon pump) {
return pump;
}
}

構(gòu)建對象圖

@Inject 和 @Provides 修飾的類組成了一個對象圖,而其中的元素因依賴而連接。而應(yīng)用的入口點(diǎn),就需要拿到這個圖的一個根的集合(這牽扯到數(shù)據(jù)結(jié)構(gòu)了,數(shù)據(jù)結(jié)構(gòu)里的樹有一個根,而圖可以有多個根,從這個根,連接到一系列節(jié)點(diǎn)構(gòu)成一顆樹)。Dagger 通過 Component 提供這個圖的根的集合。只有拿到 Component, Dagger 才能按照約定構(gòu)造所有依賴的實(shí)例。

Component 是一個 @Component 修飾的接口,它定義一系列無參數(shù)方法,返回需要的類型。Dagger 會生成它的實(shí)現(xiàn)類,該類命名是在接口名前加 Dagger(如果你是用的Android Studio,要點(diǎn)編譯按鈕后才會生成實(shí)現(xiàn)類)。

@Component 注解還可以傳一個參數(shù),modules,即該 Component 所依賴的 Module。

@Component(modules = DripCoffeeModule.class)
interface CoffeeShop {
  CoffeeMaker maker();
}

在應(yīng)用的入口點(diǎn),通過 Component 的 builder 構(gòu)造 Component 的實(shí)例,需要手動創(chuàng)建一個 Module 的實(shí)例。

CoffeeShop coffeeShop = DaggerCoffeeShop.builder()
    .dripCoffeeModule(new DripCoffeeModule())
    .build();

總結(jié)

我們一塊學(xué)習(xí)了 Dagger 中最基本的概念:

  1. @Inject 聲明依賴
  2. @Provides 我們自定義如何提供一個實(shí)例
  3. @Module 修飾一個類,它內(nèi)部可以定義多個 @Provides 修飾的方法
  4. @Component 修飾一個接口,它定義了依賴形成的圖的一系列根。啟動這個構(gòu)造系統(tǒng)的×××。

本文主要參考了,Dagger 官方文檔。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI