Dagger2 源码简析

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。

类图:

Dagger2 源码简析_第1张图片
03.png

在MainActivity中会调用以下代码:


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

去看看DaggerAppComponent源码:

Dagger2 源码简析_第2张图片
05.png
  1. 调用build方法创建出DaggerAppComponent实例。
  2. 在创建DaggerAppComponent实例时,调用了initialize(builder),创建AppModule_ProvideManagerFactory 和MainActivity_MembersInjector 实例,调用了相对应create的方法。

MainActivity_MembersInjector 源码:

Dagger2 源码简析_第3张图片
06.png
  1. 调用create的方法创建实例时 传入了 AppModule_ProvideManagerFactory 作为参数。

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

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

看看AppModule_ProvideManagerFactory的源码:

Dagger2 源码简析_第4张图片
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();
    }


}

类图:

Dagger2 源码简析_第5张图片
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;

}

类图:

Dagger2 源码简析_第6张图片
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。

你可能感兴趣的:(Dagger2 源码简析)