你所看到较轻松的Dagger2(源码分析)

上篇我们介绍完了Dagger2的详细使用方式,这篇我们分析一下Dagger2为什么这么神奇,它是怎么进行依赖注入的.我们一起解开它神秘的面纱.
当我们在宿主中调用依赖注入后build一下我们发现生成了一些class
我们先从头开始分析也就是宿主跟依赖之间的桥梁Component

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.boboyuwu.dagger2;

import com.boboyuwu.dagger2.BaseView;
import com.boboyuwu.dagger2.Compnoent;
import com.boboyuwu.dagger2.DemoPresenter;
import com.boboyuwu.dagger2.DemoPresenter_Factory;
import com.boboyuwu.dagger2.MainActivity;
import com.boboyuwu.dagger2.MainActivity_MembersInjector;
import com.boboyuwu.dagger2.Module;
import com.boboyuwu.dagger2.Module_GetBaseViewFactory;
import dagger.MembersInjector;
import dagger.internal.Preconditions;
import javax.inject.Provider;

public final class DaggerCompnoent implements Compnoent {
    private Provider<BaseView> getBaseViewProvider;
    private Provider<DemoPresenter> demoPresenterProvider;
    private MembersInjector<MainActivity> mainActivityMembersInjector;

    private DaggerCompnoent(DaggerCompnoent.Builder builder) {
        assert builder != null;

        this.initialize(builder);
    }

    public static DaggerCompnoent.Builder builder() {
        return new DaggerCompnoent.Builder();
    }

    private void initialize(DaggerCompnoent.Builder builder) {
        this.getBaseViewProvider = Module_GetBaseViewFactory.create(builder.module);
        this.demoPresenterProvider = DemoPresenter_Factory.create(this.getBaseViewProvider);
        this.mainActivityMembersInjector = MainActivity_MembersInjector.create(this.demoPresenterProvider);
    }

    public void inject(MainActivity mainActivity) {
        this.mainActivityMembersInjector.injectMembers(mainActivity);
    }

    public static final class Builder {
        private Module module;

        private Builder() {
        }

        public Compnoent build() {
            if(this.module == null) {
                throw new IllegalStateException(Module.class.getCanonicalName() + " must be set");
            } else {
                return new DaggerCompnoent(this);
            }
        }

        public DaggerCompnoent.Builder module(Module module) {
            this.module = (Module)Preconditions.checkNotNull(module);
            return this;
        }
    }
}

代码有点长,我们看到生成了一个以Dagger开头的Compnoent类在它的构造中调用了initialize(builder),这个builder参数是我们调用

 DaggerCompnoent.builder().module(new Module(this)).build()

传进去的你不信?不信我们瞧瞧,
我们调用DaggerCompnoent.builder()的时候会帮我们创建一个

public static Builder builder() {
    return new Builder();
  }

对象并将这个对象返回,然后调用module(new Module(this))的时候会把传递进去的Module赋值给Builder成员变量这里传的就是我们的Module对象

    public Builder module(Module module) {
       this.module = Preconditions.checkNotNull(module);
       return this;
   }

然后调用build()方法

    public Compnoent build() {
      if (module == null) {
        throw new IllegalStateException(Module.class.getCanonicalName() + " must be set");
      }
      return new DaggerCompnoent(this);
    }

哎呀,原来DaggerCompnoent是在这里创建的此时就会走我们上面说的initialize(builder)方法并把这个Bulider对象传递进去.
我们看看initialize(builder)方法干了些什么

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {

    this.getBaseViewProvider = Module_GetBaseViewFactory.create(builder.module);

    this.demoPresenterProvider = DemoPresenter_Factory.create(getBaseViewProvider);

    this.mainActivityMembersInjector = MainActivity_MembersInjector.create(demoPresenterProvider);
  }

我们先分析第一行看命名貌似是创建了一个工厂类对象我们点进去看看484这样,

  public static Factory<BaseView> create(Module module) {
    return new Module_GetBaseViewFactory(module);
  }

create中创建了一个Module_GetBaseViewFactory对象,这个对象是啥玩意我们继续点进去看看,

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class Module_GetBaseViewFactory implements Factory<BaseView> {
  private final Module module;

  public Module_GetBaseViewFactory(Module module) {
    assert module != null;
    this.module = module;
  }

  @Override
  public BaseView get() {
    return Preconditions.checkNotNull(
        module.getBaseView(), "Cannot return null from a non-@Nullable @Provides method");
  }

  public static Factory<BaseView> create(Module module) {
    return new Module_GetBaseViewFactory(module);
  }
}

我们看到有个get方法里面调用了module.getBaseView()这个module就是我们之前传到Builder成员变量中的那个,而getBaseView()就是我们之前获取传递到Module中的那个宿主类的方法,这么返回的就是我们的宿主类对象了. 第一行分析完毕继续分析第二行:
this.demoPresenterProvider = DemoPresenter_Factory.create(this.getBaseViewProvider);
看命名貌似也是创建一个工厂类,那么484这样子捏,点进去看看

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class DemoPresenter_Factory implements Factory<DemoPresenter> {
  private final Provider<BaseView> baseViewProvider;

  public DemoPresenter_Factory(Provider<BaseView> baseViewProvider) {
    assert baseViewProvider != null;
    this.baseViewProvider = baseViewProvider;
  }

  @Override
  public DemoPresenter get() {
    return new DemoPresenter(baseViewProvider.get());
  }

  public static Factory<DemoPresenter> create(Provider<BaseView> baseViewProvider) {
    return new DemoPresenter_Factory(baseViewProvider);
  }
}

跟之前的差不多一样,这个get()方法里创建了一个DemoPresenter对象也就是我们需要依赖注入的对象,这个对象构造里面传递了一个baseViewProvider.get()这个是什么鬼,可以看到baseViewProvider是从工厂类的构造中传过来的我们回到上一层看看这个是什么东东

 private Provider<BaseView> getBaseViewProvider;

 private void initialize(DaggerCompnoent.Builder builder) {
        this.getBaseViewProvider = Module_GetBaseViewFactory.create(builder.module);
        this.demoPresenterProvider = DemoPresenter_Factory.create(this.getBaseViewProvider);
        this.mainActivityMembersInjector = MainActivity_MembersInjector.create(this.demoPresenterProvider);
    }

原来这个就是第一行生成的工厂类对象啊

public final class Module_GetBaseViewFactory implements Factory<BaseView>

原来它继承Factory,Factory是个空接口它又继承Provider接口,Provider里面定义了一个get()方法,这里定义get()应该是统一用工厂类生成对象的,
这下就清楚了,上面的



  @Override
  public DemoPresenter get() {
    return new DemoPresenter(baseViewProvider.get());
  }

  public static Factory<DemoPresenter> create(Provider<BaseView> baseViewProvider) {
    return new DemoPresenter_Factory(baseViewProvider);
  }

原来是传入第一行Module_GetBaseViewFactory工厂类对象,get()方法中创建我们的依赖类DemoPresenterDemoPresenter中的构造参数正是调用传过来的Module_GetBaseViewFactory对象的get()生成的宿主类对象BaseView,这下我们完全清晰了

接下来继续分析第三行:

 this.mainActivityMembersInjector = MainActivity_MembersInjector.create(this.demoPresenterProvider);

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final Provider<DemoPresenter> mDemoPresenterProvider;

  public MainActivity_MembersInjector(Provider<DemoPresenter> mDemoPresenterProvider) {
    assert mDemoPresenterProvider != null;
    this.mDemoPresenterProvider = mDemoPresenterProvider;
  }

  public static MembersInjector<MainActivity> create(
      Provider<DemoPresenter> mDemoPresenterProvider) {
    return new MainActivity_MembersInjector(mDemoPresenterProvider);
  }

  @Override
  public void injectMembers(MainActivity instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.mDemoPresenter = mDemoPresenterProvider.get();
  }

  public static void injectMDemoPresenter(
      MainActivity instance, Provider<DemoPresenter> mDemoPresenterProvider) {
    instance.mDemoPresenter = mDemoPresenterProvider.get();
  }
}

create方法会传入我们第二行生成的demoPresenterProvider而这个对象可以调用get()生成DemoPresenter(BaseView view)对象而DemoPresenter对象中的构造参数又是通过第一行生成的getBaseViewProvider对象调用get()获取到的Module中的Provide提供的

@Provides
    public BaseView getBaseView(){
        return mBaseView;
    }

拿到的BaseView对象,至此所有的思路都缕顺了,当我们在宿主类中调用
DaggerCompnoent.builder().module(new Module(this)).build().inject(this); 的inject(this);方法时
会去最终调用到DaggerCompnoent的

@Override
  public void inject(MainActivity mainActivity) {
    mainActivityMembersInjector.injectMembers(mainActivity);
  }

方法然后会调用我们上面第三行生成的mainActivityMembersInjector
对象的injectMembers(mainActivity);方法,

  public static void injectMDemoPresenter(
      MainActivity instance, Provider<DemoPresenter> mDemoPresenterProvider) {
    instance.mDemoPresenter = mDemoPresenterProvider.get();
  }

这里就会把第二行生成的DemoPresenter 对象注入到最初inject()中传的宿主类中

好了Dagger2的使用方法以及源码实现原理已经全部分析完毕。初次动笔,大家捧个场,给个赞把o(∩_∩)o

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,547评论 4 374
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,787评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,175评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,752评论 0 223
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,169评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,056评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,195评论 2 321
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,980评论 0 214
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,724评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,872评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,344评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,667评论 3 264
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,379评论 3 245
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,202评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,992评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,189评论 2 286
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,987评论 2 279

推荐阅读更多精彩内容