你所看到较轻松的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()方法中创建我们的依赖类DemoPresenter
而DemoPresenter
中的构造参数正是调用传过来的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
- 你所看到较轻松的Dagger2(源码分析)
- 你所看到较轻松的Dagger2(基础介绍)
- 你所看到较轻松的Dagger2(使用方式)
- 你所看到较轻松的Dagger2(使用扩展)
- Dagger2的使用以及源码分析
- dagger2的生成源码简单分析
- 让领导看到你所做的
- 我所理解的Dagger2
- 我所理解的Dagger2
- 公交车所看到的......
- 轻松学,听说你还没有搞懂 Dagger2
- [Android源码分析]蓝牙搜索过程中你所不知道的小细节
- 放轻松,放轻松,你所要做的不过是面对一面镜子而已
- 你所不知道的马化腾:腾讯成功的较完整版本
- 你所不知道的马化腾:腾讯成功的较完整版本
- 你所不知道的马化腾:腾讯成功的较完整版本
- 你所不知道的马化腾:腾讯成功的较完整版本
- 怎么在Myeclipse中看到你想要看到的源码
- Oracle dba和sysdba的区别
- 重建二叉树(前序遍历和中序遍历)
- [置顶] Android 面试题目之一:大整形相加
- Android基于Window.ID_ANDROID_CONTENT给定id添加子View
- 我推荐阅读的微信公众号-人文类
- 你所看到较轻松的Dagger2(源码分析)
- [置顶] 自己动手实现OpenGL-OpenGL原来如此简单(三)
- 【C++】友元与静态成员
- [置顶] Android面试题目之二:整形转换为字符串
- CSS 选择器
- 点击按钮获取当前位置
- [置顶] Android面试题目之三: 字符串转整形
- HAUTOJ 1282--ykc想吃好吃的
- 度度熊与邪恶大魔王(dp)打boss2