前言
本篇文章的源码分析来源于对一篇博客的深度分析,关于dagger2的来源介绍以及具体如何使用请参考这篇博客,附上链接 https://www.cnblogs.com/tangpj/p/9874133.html
博客中所列的Dagger2Simple中的simple modules源码github地址:Dagger2Simple就是Demo地址,上面的例子为Dagger2Simple中的simple Modules
Gradle配置
//dagger2
implementation 'com.google.dagger:dagger-android:2.17'
implementation 'com.google.dagger:dagger-android-support:2.17' // if you use the support libraries
implementation 'com.google.dagger:dagger:2.17'
annotationProcessor 'com.google.dagger:dagger-compiler:2.17'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.17'
Dagger2 For Android 使用要点分析
1.CookModules
import dagger.Module;
import dagger.Provides;
@Module
public class CookModules {
@Provides
public Map providerMenus(){
Map menus = new LinkedHashMap<>();
menus.put("酸菜鱼", true);
menus.put("土豆丝", true);
menus.put("铁板牛肉", true);
return menus;
}
}
CookModule很简单,它的目的就是通过@Providers注解提供Menu对象需要的数据。因为Menu是需要依赖一个Map对象的,所以我们通过CookModules给它构造一个Map对象,并自动把它注入到Menu实例里面。
2.ActivityModules
@Module
abstract class ActivityModules {
@ContributesAndroidInjector
abstract MainActivity contributeMainActivity();
}
ActivityModules的主要作用就是通过@ContributesAndroidInjector来标记哪个类需要使用依赖注入功能,这里标记的是ManActivity,所以MainActivity能通过@Inject注解来注入Chef对象。在这里也可以增加你要拓展的Activity。
3.CookAppComponent
import javax.inject.Singleton;
import dagger.Component;
import dagger.android.AndroidInjector;
import dagger.android.support.AndroidSupportInjectionModule;
@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
ActivityModules.class,
CookModules.class
})
public interface CookAppComponent extends AndroidInjector {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder{}
}
CookAppComponent相当于一个注射器,我们前面定义的Modules就是被注射的类,使用@Inject注入对象的地方就是接收者类。
4.MyApplication
public class MyApplication extends DaggerApplication {
@Inject
Chef chef;
@Override
public void onCreate() {
super.onCreate();
}
@Override
protected AndroidInjector extends DaggerApplication> applicationInjector() {
//application中构建注射器
return DaggerCookAppComponent.builder().create(this);
}
}
MyAppliction的特点是继承了DaggerAppliction类,并且在applicationInjector方法中构建了一个DaggerCookAppComponent注射器。
其实只知道这么去用,心里还是会感觉知其然,不知其所以然,一图胜千言,先上图吧!
从图中我们就可以清晰的看到从上至下大致可以分为三层,最上层可以看做dagger2的Engine部分,为我们分离抽象出了对象创建或注入的基本分装,当然还包含我没列出来的对Android四大组件注入的基本封装。
最下层为dagger采用的APT+JavaPoet技术通过静态编译为我们生成的代码,这里不再细说。
中间层为用户层,我们只需关心我们要inject哪些对象,如何provider对象并且封装成不同module然后存放在Component中基本上就可以了。再深入点掌握好@Singleton如何提供全局实例,这样比如在平时项目中我们封装的okhttpclient, sqlite obj, sharedprefrence就不用我们手动去写一堆代码了。更多的比如@Scope最好要掌握自定义Scope, 还有@Names, @Binds, @Lazy 等用法大家也可以在上面的博客和Dagger2官网多看看。
重点源码剖析
CookAppComponent接口作为全局的唯一注入入口,Dagger2为我们生成了核心的类DaggerCookAppComponent,通过MyApplication中的一句代码注册,大家可以根据图片一览整个类的调用流程。结合源码我们看到它承载着Application的初始化,Activity、Fragment、Service、BroadCastReceiver、ContentProvider的构建,还有四大组件的members如何与各个组件间绑定,以及Modules的初始化和modules工厂对象的构建实现等。
总结
通过对Dagger2核心源码的分析以及UML图的制作,我们确实体会到了dagger2的高级分层设计思想与代码的抽象封装能力。Dagger2实现依赖注入的方式非常有趣,能掌握这项技术的话,对我们的提升是非常大的,希望各位读者在阅读了本文后能够去体验一下。如果喜欢的话,也请点个赞哦~