Dagger2 源码简析

作者: maimingliang | 来源:发表于2016-12-25 23:16 被阅读542次

Dagger2是首个使用生成代码实现完整依赖注入的框架,极大减少了使用者的编码负担。
我们去看看Dagger2 是如何为我们注入对象的。

假设我们需要在MainActivity中注入对象DataManager:

public class MainActivity extends AppCompatActivity {

    @Inject
    DataManager dataManager;

}

使用@Inject标志被注入的对象dataManager(注意dataManager不能为private)

Dagger2中,负责提供依赖的组件被称为Module。
创建Module类,如下:

@Module
public class AppModule {


    /**
     * 带@Provides 注解 ,说明该方法是提供依赖
     * @return
     */
    @Provides
    public DataManager provideManager() {
        return new DataManager();
    }

}

使用@Module注解来标识类型为module,并用@Provides标识提供依赖的方法。

Dagger2中,我们需要Component 来连接 Module 和 @Inject 来完成对象的注入:
创建 Component接口:


@Component(modules = {AppModule.class})
@Singleton
public interface AppComponent {

    void inject(MainActivity activity);
}

使用@Component注解来标识类型为Component,参数modules 可以依赖多个module。
接口中的inject方法需要该注入对象所在的类作为参数。注意:这里必须是注入对象所在的类MainActivity,而不可以写成其父类。

编译。

Dagger2 会生成一些辅助类。

带@Component注解 :生成 Dagger_(带@Component注解接口名称)。这里是AppComponent。因此会生成 Dagger_AppComponent;

带@Module 注解 :生成 (带@Mudule类名)_(带@Provides注解的方法名)Factory。这里是 AppModule_ProvideManagerFactory

带@Inject 注解:生成 (需要注入对象所在的类名)_MembersInjector。
这里是MainActivity_MembersInjector。

类图:

03.png

在MainActivity中会调用以下代码:


 DaggerAppComponent
                .builder()
                .appModule(new AppModule())
                .build()
                .inject(this);

去看看DaggerAppComponent源码:

05.png
  1. 调用build方法创建出DaggerAppComponent实例。
  2. 在创建DaggerAppComponent实例时,调用了initialize(builder),创建AppModule_ProvideManagerFactory 和MainActivity_MembersInjector 实例,调用了相对应create的方法。

MainActivity_MembersInjector 源码:

06.png
  1. 调用create的方法创建实例时 传入了 AppModule_ProvideManagerFactory 作为参数。

  2. 但 .inject(this)方法时,调用了injectMembers方法,看到这个方法,可以知道为什么datamanage 不能为private和为什么调用inject方法传参数时不能写父类了。

  3. dataManage 实例的创建调用了AppModule_ProvideManagerFactory的get方法。

看看AppModule_ProvideManagerFactory的源码:

04.png

可以看到,get方法其实调用了AppModule 的provideManager方法,而这个方法new DataManager();完成对象的注入。

这就是Dagger2 为我们注入对象处理的流程。

我们在MainActivity 再注入一个对象Person,看看Dagger2 生成了怎么样的辅助类。

修改如下:
MainActivity :


public class MainActivity extends AppCompatActivity {

    @Inject
    DataManager dataManager;

    @Inject
    Person person;
}

修改AppModule:


@Module
public class AppModule {


    /**
     * 带@Provides 注解 ,说明该方法是提供依赖
     * @return
     */
    @Provides
    public DataManager provideManager() {
        return new DataManager();
    }


    @Provides
    public Person providePerson(){
        return new Person();
    }


}

类图:

08.png

如果是多层依赖 又会生成什么辅助类?

添加 UserModule :


@Module
public class UserModule {


    @Provides
    public User provideUser(){
        return new User();
    }
}

修改AppComponent


@Component(modules = {AppModule.class,UserModule.class})
@Singleton
public interface AppComponent {

    void inject(MainActivity activity);
}

修改MainActivity


public class MainActivity extends AppCompatActivity {


    @Inject
    DataManager dataManager;


    @Inject
    Person person;


    @Inject
    User user;

}

类图:

09.png

可以看出

  1. Component 只是 Module 和 Inject 中间的桥梁
  2. Module 相当于简单工厂,提供了各种依赖

辅助类的生成规则:

带@Component注解 :生成 Dagger_(带@Component注解接口名称)。这里是AppComponent。因此会生成 Dagger_AppComponent;

带@Module 注解 :生成 (带@Mudule类名)_(带@Provides注解的方法名)Factory。这里是 AppModule_ProvideManagerFactory

带@Inject 注解:生成 (需要注入对象所在的类名)_MembersInjector。
这里是MainActivity_MembersInjector。

END。

相关文章

  • mybatis-spring解析

    1、概述 原生Mybatis源码简析(上)原生Mybatis源码简析(下)在介绍原生Mybatis源码简析文章中,...

  • dagger2源码简析

    介绍 关于dagger github上是这样介绍的。 A fast dependency injector for...

  • Dagger2 源码简析

    Dagger2是首个使用生成代码实现完整依赖注入的框架,极大减少了使用者的编码负担。我们去看看Dagger2 是如...

  • Flink自定义StreamOperator

    在上一篇StreamOperator源码简析从源码角度分析了StreamOperator以及其实现类,此篇幅主要分...

  • OkHttp源码简析

    Android平台有很多优秀的开源库,OkHttp绝对是其中的佼佼者,它是Square出品的一个网络通讯库,功能强...

  • HashMap源码简析

    说到HashMap相信大家并不陌生,这是一个非常常用的以键值对形式存储的数据结构,但是对其内部原理可能不是很了解,...

  • Handler源码简析

    消息------Message 消息的复用:Message.obtain() public static M...

  • Mask源码简析

    版本 源码版本:2017.3.0 着色器版本:2017.3.0 Mask使用方法 https://jingyan....

  • Wax源码简析

    阅读的是阿里维护的Wax版本 先针对如下用法的实现过程进行讲解。 用法 用法讲解 详细的Wax用法讲解,请参阅ht...

  • Mybatis源码简析

    本文将按mybatis中主要数据库查询操作的流程对其源码进行简单分析。目录如下: 1、mybatis的主要工作流程...

网友评论

    本文标题:Dagger2 源码简析

    本文链接:https://www.haomeiwen.com/subject/hetrvttx.html