ARouter源碼解析(三)

arouter-api version : 1.4.1

前言

到現(xiàn)在為止,ARouter 還有最后的依賴注入還沒有解析過斟冕,那么今天就來深入探究一下其實現(xiàn)原理。

PS : 因為依賴注入的原理還比較簡單缅阳,所以本篇篇幅會較短磕蛇。

@Autowired解析

想要用 ARouter 實現(xiàn)依賴注入,需要在 Activity/Fragment 中加上

ARouter.getInstance().inject(this);

那么我們這個代碼就成為了我們分析的入口了十办。

public void inject(Object thiz) {
    _ARouter.inject(thiz);
}

ARouter 內(nèi)部還是調(diào)用了 _ARouter 的 inject 方法秀撇。

static void inject(Object thiz) {
    AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
    // 如果 autowiredService 不為空,完成依賴注入
    if (null != autowiredService) {
        autowiredService.autowire(thiz);
    }
}

發(fā)現(xiàn)依賴注入和攔截器很相似向族,都是利用服務組件來完成的呵燕。依賴注入的服務組件叫 AutowiredService ,跟蹤可以發(fā)現(xiàn)件相,它的實現(xiàn)類是 AutowiredServiceImpl 再扭。

@Route(path = "/arouter/service/autowired")
public class AutowiredServiceImpl implements AutowiredService {
    private LruCache<String, ISyringe> classCache;
    private List<String> blackList;

    @Override
    public void init(Context context) {
        classCache = new LruCache<>(66);
        blackList = new ArrayList<>();
    }

    @Override
    public void autowire(Object instance) {
        String className = instance.getClass().getName();
        try {
            // 如果 instance 這個類進入黑名單了燕酷,就不會完成依賴注入
            if (!blackList.contains(className)) {
                // 先從緩存中取
                ISyringe autowiredHelper = classCache.get(className);
                // 沒有緩存就創(chuàng)建對象
                if (null == autowiredHelper) {  // No cache.
                    autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
                }
                // 完成依賴注入
                autowiredHelper.inject(instance);
                // 放入緩存中
                classCache.put(className, autowiredHelper);
            }
        } catch (Exception ex) {
            // 出錯就加入黑名單中
            blackList.add(className);    // This instance need not autowired.
        }
    }
}

其中 ISyringe 就是依賴注入抽取出來的接口衡便,

public interface ISyringe {
    void inject(Object target);
}

那么 ISyringe 的實現(xiàn)類又是誰呢贷掖?答案就是在編譯期自動生成的類 XXXX$$ARouter$$Autowired 乔外,我們找 demo 中生成的 Test1Activity$$ARouter$$Autowired 來看看

public class Test1Activity$$ARouter$$Autowired implements ISyringe {
  private SerializationService serializationService;

  @Override
  public void inject(Object target) {
    serializationService = ARouter.getInstance().navigation(SerializationService.class);
    Test1Activity substitute = (Test1Activity)target;
    substitute.name = substitute.getIntent().getStringExtra("name");
    substitute.age = substitute.getIntent().getIntExtra("age", substitute.age);
    substitute.height = substitute.getIntent().getIntExtra("height", substitute.height);
    substitute.girl = substitute.getIntent().getBooleanExtra("boy", substitute.girl);
    substitute.ch = substitute.getIntent().getCharExtra("ch", substitute.ch);
    substitute.fl = substitute.getIntent().getFloatExtra("fl", substitute.fl);
    substitute.dou = substitute.getIntent().getDoubleExtra("dou", substitute.dou);
    substitute.ser = (com.alibaba.android.arouter.demo.testinject.TestSerializable) substitute.getIntent().getSerializableExtra("ser");
    substitute.pac = substitute.getIntent().getParcelableExtra("pac");
    if (null != serializationService) {
      substitute.obj = serializationService.parseObject(substitute.getIntent().getStringExtra("obj"), new com.alibaba.android.arouter.facade.model.TypeWrapper<TestObj>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'obj' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
    }
    if (null != serializationService) {
      substitute.objList = serializationService.parseObject(substitute.getIntent().getStringExtra("objList"), new com.alibaba.android.arouter.facade.model.TypeWrapper<List<TestObj>>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'objList' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
    }
    if (null != serializationService) {
      substitute.map = serializationService.parseObject(substitute.getIntent().getStringExtra("map"), new com.alibaba.android.arouter.facade.model.TypeWrapper<Map<String, List<TestObj>>>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'map' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
    }
    substitute.url = substitute.getIntent().getStringExtra("url");
    substitute.helloService = ARouter.getInstance().navigation(HelloService.class);
  }
}

從上面自動生成的代碼中看出來渊迁,依賴注入實際上內(nèi)部還是使用 getIntent.getXxxExtra 的形式來賦值的(同理钱骂,F(xiàn)ragment 用的是getArguments().getXxx() )屋厘。需要注意的是紧索,@Autowired 修飾的字段不能是 private 的,不然在自動生成代碼的時候會報錯区赵。

另外惭缰,上面的代碼中有一個 SerializationService 是用來干什么的?其實 SerializationService 是 json 序列化用的笼才。在 demo 中官方給出了一個實現(xiàn)類 JsonServiceImpl 漱受,內(nèi)部用的是阿里的 fastjson 。如果有需要自定義的童鞋患整,可以參照著 JsonServiceImpl 自己去實現(xiàn)拜效。

結束

看到這,基本上 ARouter 依賴注入的東西就講完了各谚。

這一系列下來紧憾,ARouter 代碼層面的流程都講的差不多。剩下就是 gradle-plugin 和 compiler 這兩個部分還沒解析過昌渤,等時間了再給大家講赴穗。

bye bye

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市膀息,隨后出現(xiàn)的幾起案子般眉,更是在濱河造成了極大的恐慌,老刑警劉巖潜支,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甸赃,死亡現(xiàn)場離奇詭異,居然都是意外死亡冗酿,警方通過查閱死者的電腦和手機埠对,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裁替,“玉大人项玛,你說我怎么就攤上這事∪跖校” “怎么了襟沮?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昌腰。 經(jīng)常有香客問我开伏,道長,這世上最難降的妖魔是什么剥哑? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任硅则,我火速辦了婚禮,結果婚禮上株婴,老公的妹妹穿的比我還像新娘怎虫。我一直安慰自己暑认,他們只是感情好,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布大审。 她就那樣靜靜地躺著蘸际,像睡著了一般。 火紅的嫁衣襯著肌膚如雪徒扶。 梳的紋絲不亂的頭發(fā)上粮彤,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天,我揣著相機與錄音姜骡,去河邊找鬼导坟。 笑死,一個胖子當著我的面吹牛圈澈,可吹牛的內(nèi)容都是我干的惫周。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼康栈,長吁一口氣:“原來是場噩夢啊……” “哼递递!你這毒婦竟也來了?” 一聲冷哼從身側響起啥么,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤登舞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后悬荣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體菠秒,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年氯迂,在試婚紗的時候發(fā)現(xiàn)自己被綠了稽煤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡囚戚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出轧简,到底是詐尸還是另有隱情驰坊,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布哮独,位于F島的核電站拳芙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏皮璧。R本人自食惡果不足惜舟扎,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悴务。 院中可真熱鬧睹限,春花似錦譬猫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至叨恨,卻和暖如春柳刮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背痒钝。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工秉颗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人送矩。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓蚕甥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親益愈。 傳聞我的和親對象是個殘疾皇子梢灭,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

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

  • ARouter源碼解讀 以前看優(yōu)秀的開源項目,看到了頁面路由框架ARouter蒸其,心想頁面路由是個啥東東敏释,于是乎網(wǎng)上...
    陸元偉閱讀 531評論 0 1
  • 終于來到了ARouter解析的第五篇了,前面陸陸續(xù)續(xù)分享了四篇ARouter框架的使用和源碼內(nèi)容: ARouter...
    juexingzhe閱讀 6,803評論 1 8
  • 前言 隨著項目業(yè)務邏輯和功能點日益遞增, 邏輯的耦合程度也逐漸升高, 組件化技術可以很好的解決這個問題, 公司大佬...
    SharryChoo閱讀 1,100評論 0 9
  • 我是只很有上進心的猴子摸袁,為了“提高”钥顽,忍痛割掉了那本該伴我終生的尾巴,幻化成人的模樣靠汁,混跡其中蜂大,模仿著他們的行為,...
    danli227閱讀 249評論 0 1
  • 竹籬茅舍柴扉開蝶怔, 游客如云不長苔奶浦。 酒幌飄揚香稻地, 奇花異果李紈栽踢星? 注:稻香村原為賈寶玉的寡嫂李紈的住所澳叉。 2...
    江德豐閱讀 913評論 22 19