Dagger2 — 通過注解實現(xiàn)依賴注入一種方式

本片文章將介紹Dagger2的作用及使用方式职车。

什么是Dagger2渴庆?

  • Dagger2是在編譯時期生成代碼實現(xiàn)完整依賴注入的框架

Dagger 2 is a compile-time evolution approach to dependency injection. Taking the approach started in Dagger 1.x to its ultimate conclusion, Dagger 2.x eliminates all reflection, and improves code clarity by removing the traditional ObjectGraph/Injector in favor of user-specified @Component interfaces.

什么是依賴注入家妆?

  • 依賴注入作用
    • 是實現(xiàn)控制反轉(zhuǎn)(Inversion of Control)的最常見的方式之一

      控制反轉(zhuǎn) 是一種面向?qū)ο缶幊讨械囊环N設計原則对省,用來減低計算機代碼之間的耦合度炬藤。其基本思想是:借助于“第三方”實現(xiàn)具有依賴關系的對象之間的解耦。

      簡單說就是如果對象A依賴于對象B饺窿,那么對象A自己需要主動去創(chuàng)建對象B歧焦,無論是創(chuàng)建還是使用對象B,控制權都在自己手上肚医。而控制反轉(zhuǎn)的思想是對象A與對象B之間失去直接聯(lián)系绢馍,當對象A需要對象B的時候,IOC容器會主動創(chuàng)建一個對象B注入到對象A需要的地方肠套。

    • 目的在于解耦

      • 常見耦合場景:一個類中直接創(chuàng)建另一個類的對象的代碼舰涌,這樣的操作和硬編碼一樣,會導致耦合你稚,我們把這種初始化方式稱為硬初始化(hard init)瓷耙。
      • 硬初始化的壞處:
        • 修改構(gòu)造函數(shù)實現(xiàn)時朱躺,需要修改創(chuàng)建處的代碼
        • 不便于測試,直接創(chuàng)建另一個類對象的類無法單獨被測試搁痛,其行為和另一個類緊緊耦合在一起长搀,同時,也會導致代碼的可讀性問題鸡典。
  • 依賴注入常見3種方式:
    • 構(gòu)造函數(shù)注入
      public class MovieLister {
         private MovieFinder finder;
         public MovieLister(MovieFinder finder) {
           this.finder = finder;
           }
        ...
      }
      
    • setter注入
        public class MovieLister {
          ...
           public void setFinder(MovieFinder finder) {
             this.finder = finder;
          }
       }
      
    • 接口注入
        public interface InjectFinder {
          void injectFinder(MovieFinder finder);
        }
      
       class MovieLister implements InjectFinder {
           ...
          public void injectFinder(MovieFinder finder) {
             this.finder = finder;
           }
         ...
       }
      

使用Dragger2進行依賴注入

  • 常見的硬初始化代碼
public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        UserModel user = new UserModel();
        ((TextView) findViewById(R.id.user_desc_line)).setText(user.id + "\n" + user.name + "\n" + user.gender);
    }
    ...
}

一但UserModel的構(gòu)造發(fā)生改變那么我們要修改所有實例化UserModel的代碼骏全。

  • 使用Dagger2實現(xiàn)方式
    • 目標:對于依賴類的修改不影響使用該類實例的類代碼
    • 步驟:
      • 構(gòu)建依賴

        • 將創(chuàng)建對象的代碼隔離起來顾瞪,保證使用的類不受其后期更改影響
        • 負責提供依賴的組件被稱為Module
           @Module
           public class ActivityModule {
            @Provides UserModel provideUserModel() {
                return new UserModel();
               }
            } 
        
        • 使用@Module標識該類為Module野蝇,并用@Provides標識提供依賴的方法晰赞。
      • 構(gòu)建Injector

        • 將依賴注入到需要的對象中
        • 連接提供依賴和消費依賴對象的組件被稱為Injector。Dagger2中疗垛,我們將其稱為component症汹。
          @Component(modules = ActivityModule.class)
              public interface ActivityComponent {
                  void inject(MainActivity activity);
              }
        
        • Component是一個使用@Component標識的Java 接口。接口的inject方法入?yún)樾枰撘蕾嚨念愋汀?/li>
        • 注意:這里必須是真正消耗依賴的類型MainActivity贷腕,而不可以寫成其父類背镇,比如Activity。因為Dagger2在編譯時生成依賴注入的代碼泽裳,會到inject方法的參數(shù)類型中尋找可以注入的對象瞒斩,但是實際上這些對象存在于MainActivity,而不是Activity中涮总。所以如果函數(shù)聲明參數(shù)為Activity胸囱,Dagger2在Activity中找不到要注入的對象,導致所有注入都失敗瀑梗。
      • 完成依賴注入:在需要依賴的地方創(chuàng)建Injector烹笔,完成注入

           public class MainActivity extends ActionBarActivity {
            private ActivityComponent mActivityComponent;
            @Inject UserModel userModel;
            @Override
            protected void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
               setContentView(R.layout.activity_main);
               mActivityComponent = 
               DaggerActivityComponent.builder().activityModule(new ActivityModule()).build();
               mActivityComponent.inject(this);
               ((TextView) findViewById(R.id.user_desc_line)).setText(userModel.id + "\n" + userModel.name + "\n" + userModel.gender);
            }
         ...
        }
        
        • 使用@Inject標志被注入的對象userModel(注意userModel不能為private)
        • 通過Dagger2生成的實現(xiàn)ActivityComponent接口類DaggerActivityComponent創(chuàng)建component,調(diào)用其inject方法完成注入抛丽。

Dagger2通過將創(chuàng)建依賴類對象的代碼獨立起來谤职,保證使用的類不受依賴類的構(gòu)造改變而受到影響,同時通過注解在編譯時動態(tài)生成代碼注入到被依賴類中亿鲜,實現(xiàn)依賴類和被依賴類解耦允蜈。

參考文獻:

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蒿柳,隨后出現(xiàn)的幾起案子饶套,更是在濱河造成了極大的恐慌,老刑警劉巖垒探,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妓蛮,死亡現(xiàn)場離奇詭異,居然都是意外死亡圾叼,警方通過查閱死者的電腦和手機蛤克,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門扔仓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人咖耘,你說我怎么就攤上這事∏寺耄” “怎么了儿倒?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長呜笑。 經(jīng)常有香客問我夫否,道長,這世上最難降的妖魔是什么叫胁? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任凰慈,我火速辦了婚禮,結(jié)果婚禮上驼鹅,老公的妹妹穿的比我還像新娘微谓。我一直安慰自己,他們只是感情好输钩,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布豺型。 她就那樣靜靜地躺著,像睡著了一般买乃。 火紅的嫁衣襯著肌膚如雪姻氨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天剪验,我揣著相機與錄音肴焊,去河邊找鬼。 笑死功戚,一個胖子當著我的面吹牛娶眷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疫铜,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼茂浮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了壳咕?” 一聲冷哼從身側(cè)響起席揽,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谓厘,沒想到半個月后幌羞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡竟稳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年属桦,在試婚紗的時候發(fā)現(xiàn)自己被綠了熊痴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡聂宾,死狀恐怖果善,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情系谐,我是刑警寧澤巾陕,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站纪他,受9級特大地震影響鄙煤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜茶袒,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一梯刚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薪寓,春花似錦亡资、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至植康,卻和暖如春旷太,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背销睁。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工供璧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冻记。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓睡毒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親冗栗。 傳聞我的和親對象是個殘疾皇子演顾,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Dagger2是個什么東西呢?依賴注入隅居,這是個啥玩意钠至?嗯,在學這個東西的時候我們得了解一些知識點: 知識點呀 依賴...
    SHERLOCKvv閱讀 1,191評論 0 6
  • 部分內(nèi)容參考自:[Android]使用Dagger 2依賴注入 - DI介紹(翻譯)[Android]使用Dagg...
    AItsuki閱讀 47,264評論 66 356
  • 前言 使用Dagger2前你必須了解的一些設計原則Dagger2 最清晰的使用教程請先看以上兩篇文章 dagger...
    SnowDragonYY閱讀 1,023評論 0 3
  • 什么的依賴注入 在軟件工程中胎源,依賴注入是實現(xiàn)控制反轉(zhuǎn)的方式之一棉钧。百度百科中對于控制反轉(zhuǎn)的解釋如下:控制反轉(zhuǎn)(Inv...
    小甜李子閱讀 1,669評論 5 3
  • 17號晚上10點到二姨家,舅舅一家在這里等我們相聚涕蚤。今天除大姨和我爸爸沒有在場宪卿,媽媽其他姊妹都在的诵、很難得這么多親人...
    蔣泳頻閱讀 69評論 0 0