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

来源:互联网 发布:自知无知便是知 编辑:程序博客网 时间:2024/06/18 11:12

上篇我们介绍完了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的使用方法以及源码实现原理已经全部分析完毕。最后还有一篇Dagger2拓展功能介绍:
http://blog.csdn.net/boboyuwu/article/details/76821324

原创粉丝点击