Dagger 2 系列(三) -- 基礎篇:@Module 和 @Provides

Dagger2

  • 該系列博客的最終目標: 搭建 MVP + Dagger2 框架
  • 該系列博客包含如下幾篇內容:
  1. Dagger 2 系列(一) -- 前奏篇:依賴注入的基本介紹
  2. Dagger 2 系列(二) -- 基礎篇:@Inject、@Component
  3. Dagger 2 系列(三) -- 基礎篇:@Module 和@Provides
  4. Dagger 2 系列(四) -- 基礎篇:@Named 和 @Qualifier
  5. Dagger 2 系列(五) -- 進階篇:@Scope 和 @Singleton

在這篇文章中你會看到什麼:html

  • @Module 是什麼
  • @Provides 是什麼
  • @Module@Provides@Component 如何協同做戰。

1. 什麼是 Module

既然在Dagger 2 系列(二) -- 基礎篇:基本功能的實現一文中經過 @Inject@Component 咱們已經實現了 DI,那麼爲何 Dagger2 還要實現其餘的DI 方式。java

其實在上文中咱們實現的 DI 方式中咱們不難發現,經過@Inject 的註解實體類的構造函數是必不可少,它標識着 Dagger2 能夠實例化該類。那麼當你須要實例化一個第三方的對象時,是否是懵逼了,由於你不可能註解第三方類的構造函數 -- 好比說 Gson 類的構造函數。那麼如今就須要 @Module 來充分發揮做用了。git

其實Module 實際上是一個簡單工廠模式,Module 裏面的方法都是建立相應類實例的方法。github

具體什麼是 簡單工廠模式,請看代碼段簡單學習設計模式 -- 簡單工廠模式設計模式

栗子:經過 @Module 的方式得到第三方類庫的對象 -- Gson(固然也能夠得到自定義類對象)bash

@Module
public class AModule {

    @Provides
    public Gson provideGson(){
        return new Gson();
    }
}
複製代碼

你再該類中看到了兩個註解:app

  1. 經過 @Module 註解類
  2. 經過 @Provides 註解方法

1.2 添加多個 Module

一個 Component 能夠含有多個 Module ,這樣在尋找依賴實例時就會自動從多個 Module 中尋找。框架

添加 多個 Module 的方法有兩種:ide

1.2.1 Component 註解 -- @Component(modules={××××,×××})

示例代碼以下:函數

@Component(modules={ModuleA.class,ModuleB.class,ModuleC.class}) 
public interface AppComponent{
    ...
}
複製代碼
1.2.2 Module 註解 -- @Module(includes={××××,×××})

示例代碼以下:

@Module(includes={ModuleA.class,ModuleB.class,ModuleC.class})
public class FruitModule{
    ...
}
@Component(modules={FruitModule.class}) //添加多個Module
public interface AppComponent{
    ...
}
複製代碼

這種使用 Moduleincludes 添加多Module 的方法通常用於構建更高層的Module時候使用,如在本例中

2. 什麼是 Provides

@Provides 用以標註 Module 類中的方法,它的做用是 標註該 Module 能夠向外界提供的類的實例對象的方法 ,就像 AModule 中能夠提供 Gson 實例對象的 provideGson() 方法。

3. Component -- 管理 Module

此時 DI 不是經過 @Inject 註解類構造器的方式,那麼這個註解器的使用方法確定也有所變化。此時 Component 的職責是管理 Module,Component 中的屬性容許 Module 能夠加入到 Component,同時一個 Component 能夠加入多個 Module。

依賴注入的具體工做流程:

協做流程

若實例化過程當中參數一樣是須要依賴注入的,那麼須要按照上圖中的流程同樣尋找相應的方法。若是遍歷了組件中管理的 Module 類中的 @Provides 註解的方法,那麼就會尋找該實例類的構造器中是否有被 @Inject 註解的,若是參數一樣有須要依賴注入的,那麼就重複以上過程。若是最終仍是沒有找到相應的初始化實例的方法,那麼程序會報出相應的錯誤。

4. 代碼示例

@Component(modules = UserTwoModule.class)
public interface UserTwoComponent {
    void injectToSecondActivity(SecondActivity mSecondActivity);
}

@Module
public class UserTwoModule {
    @Provides
    UserTwo provideUserTwo(){
        return new UserTwo("男",1243);
    }
}

public class SecondActivity extends AppCompatActivity {
    @Inject
    UserTwo mUserTwo;
    private static final String TAG = "SecondActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
     DaggerUserTwoComponent.builder().userTwoModule(new UserTwoModule()).build().injectToSecondActivity(this);
    }
}

複製代碼

Dagger2sample github地址

總結

到此爲止,咱們已經實現了基本的基於Dagger2@Module@Provides的依賴注入。下面咱們把過程再梳理一遍:

  1. 用@Inject註解標註目標類中其餘類
  2. Module 中建立返回值爲相應實體類的方法,並用 @Provides 標註
  3. 若其餘類還依賴於其餘的類,則重複進行上面2個步驟
  4. 調用Component(注入器)的injectXXX(Object)方法開始注入(injectXXX方法名字是官方推薦的名字,以inject開始)

Component 就像媒介,鏈接 Module目標類,把目標類依賴的實例注入到目標類中,來初始化目標類中的依賴。


參考資料

Dagger 詳解

這就是Dagger2

Dagger2 入門實踐

Android:dagger2讓你愛不釋手-終結篇

最簡單的Dagger2入門教程

Android:dagger2讓你愛不釋手-基礎依賴注入框架篇

相關文章
相關標籤/搜索