Dagger2原理剖析

前言

本篇文章的源码分析来源于对一篇博客的深度分析,关于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 applicationInjector() {
        //application中构建注射器
        return DaggerCookAppComponent.builder().create(this);
    }
}

MyAppliction的特点是继承了DaggerAppliction类,并且在applicationInjector方法中构建了一个DaggerCookAppComponent注射器。

其实只知道这么去用,心里还是会感觉知其然,不知其所以然,一图胜千言,先上图吧!

Dagger2原理剖析_第1张图片
dagger2.jpeg

从图中我们就可以清晰的看到从上至下大致可以分为三层,最上层可以看做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实现依赖注入的方式非常有趣,能掌握这项技术的话,对我们的提升是非常大的,希望各位读者在阅读了本文后能够去体验一下。如果喜欢的话,也请点个赞哦~

你可能感兴趣的:(Dagger2原理剖析)