二 Dagger2的源码分析

概述:第一篇基本阐明了Dagger2的使用,本篇基于上一篇的Demo来对源码进行分析。

上一篇提到,Dagger2基本分为三个部分。第一部分是创建对象实例。第二部分是引用对象实例。第三部分是利用注入器将两者关联。那么就一个一个分析,先看第一部分:

一 创建对象实例
通过在构造器上加入@Inject来创建实例

public class Student {
   @Inject
    public Student() {

    }
}

然后进行编译,我们会在 app\build\generated\source\apt\debug对应的目录下找到Student_Factory这个类。这个是Dagger2根据在构造器上的@Inject这个注解,自己生成的。我们看一下这个类具体是什么样的:

public final class Student_Factory implements Factory<Student> {
  private static final Student_Factory INSTANCE = new Student_Factory();

  @Override
  public Student get() {
    return provideInstance();
  }

  public static Student provideInstance() {
    return new Student();
  }

  public static Student_Factory create() {
    return INSTANCE;
  }

  public static Student newStudent() {
    return new Student();
  }
}

一眼看过去,大概就明白,这是一个Student的工厂类,通过provideInstance来自己new一个Student实例,然后通过get方法来获取自己创建出来的实例。

二 引用对象实例

public class MainActivity extends AppCompatActivity {


    @Inject
    Student student;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
}

加上这个之后,再进行编译,我们会发现,在同样的目录下又多了一个类,叫做MainActivity_MembersInjector,打开这个类,我们来看一下:

public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final Provider<Student> studentProvider;

  public MainActivity_MembersInjector(Provider<Student> studentProvider) {
    this.studentProvider = studentProvider;
  }

  public static MembersInjector<MainActivity> create(Provider<Student> studentProvider) {
    return new MainActivity_MembersInjector(studentProvider);
  }

  @Override
  public void injectMembers(MainActivity instance) {
    injectStudent(instance, studentProvider.get());
  }

  public static void injectStudent(MainActivity instance, Student student) {
    instance.student = student;
  }
}

注意看injectStudent方法,其实就是Student这个实例对象的引用,给了MainActivity中的Student。第一部分其实已经把Student对象创建好了,现在要做的就是把他们关联起来。于是就用到了注入器:

三 将两者进行关联
这里需要两步操作,第一:先生成注入器:

@Component
public interface MainComponent {
    void inject(MainActivity activity);
}

此时对项目进行编译,会再生成一个类DaggerMainComponent:

public final class DaggerMainComponent implements MainComponent {
  private DaggerMainComponent(Builder builder) {}

  public static Builder builder() {
    return new Builder();
  }

  public static MainComponent create() {
    return new Builder().build();
  }

  @Override
  public void inject(MainActivity activity) {
    injectMainActivity(activity);
  }

  private MainActivity injectMainActivity(MainActivity instance) {
    MainActivity_MembersInjector.injectStudent(instance, new Student());
    return instance;
  }

  public static final class Builder {
    private Builder() {}

    public MainComponent build() {
      return new DaggerMainComponent(this);
    }
  }
}

大概理一下,这个类其实是通过builder构建器模式创建对象,然后通过调用inject方法来完成注入。到这一步并不是说就注入完成了,这个注入操作得我们手动写代码完成:

public class MainActivity extends AppCompatActivity {


    @Inject
    Student student;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
               //在这里完成手动注入
                DaggerMainComponent
                .builder()
                .build()
                .inject(this);
    }

}

这里也能体现出来我们上面的分析,通过构建器创建对象,然后调用inject把MainActivity传进去,最后看这几个方法:

@Override
  public void inject(MainActivity activity) {
    injectMainActivity(activity);
  }

  private MainActivity injectMainActivity(MainActivity instance) {
    MainActivity_MembersInjector.injectStudent(instance, new Student());
    return instance;
  }


//这个方法是在MainActivity_MembersInjector这个类里面的,这里写一块是为了展示
 public static void injectStudent(MainActivity instance, Student student) {
    instance.student = student;
  }

至此,其实就应该很清楚,为什么我们通过那几个注解,就可以获取到需要注入的实例化对象了。这里还需要进行补充的是,第一部分的实例化对象有两种方式,除了在构造器上加@Inject注解,还可以通过@Module模块来提供对象,那么接下来就看一下@Module是如何提供实例化对象的。

首先把构造器上的@Inject注解注释掉,然后创建Module类

@Module
public class MainModule {


    @Provides
    static Student provideStudent(){
        return new Student();
    }

}

然后再编译一下,会发现又生成一个新的类MainModule_ProvideStudentFactory:

public final class MainModule_ProvideStudentFactory implements Factory<Student> {
  private static final MainModule_ProvideStudentFactory INSTANCE =
      new MainModule_ProvideStudentFactory();

  @Override
  public Student get() {
    return provideInstance();
  }

  public static Student provideInstance() {
    return proxyProvideStudent();
  }

  public static MainModule_ProvideStudentFactory create() {
    return INSTANCE;
  }

  public static Student proxyProvideStudent() {
    return Preconditions.checkNotNull(
        MainModule.provideStudent(), "Cannot return null from a non-@Nullable @Provides method");
  }
}

注意看这个provideInstance,通过构造器生成的对象,这里面是直接返回new Student(),而通过Module,这里面是调用了proxyProvideStudent()这个方法,而这个方法又会调用MainModule.provideStudent()。这个恰恰是我们手动写的provideStudent,在里面我们自己new了一个Student。

总结:通过对于源码的分析,我们可以更清楚的了解到为什么这么用。这样在遇到问题的时候能更好的通过源码的角度对问题进行分析。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容