这时候可能有同学又有疑问了,DaggerTeacherComponent这个类怎么报错啊 ,其实这个类是编译时产生的类大家不用慌,把代码写完了crtl+F9编译一下就可以了,但是!!!这里DaggerTeacherComponent的书写方法是Dagger加上你前面自定义的Component接口类的类名,一定要注意,不然很多同学都会在这翻车(我曾经在这儿翻出无数次),然后再说一下我们上一个问题 TeacherComponent 中的inject方法是固定方法吗?很明显这里调用的是inject(this);所以不是固定方法,只不过你Component接口类写成injectA(Teacher teacher),那么你这里调用的方法就是injectA(this)
ok,上面这些都写好了,我们在Teacher类中添加测试类来测试测试
public class Teacher { //想持有学生对象 @Inject Student student; public Teacher() { DaggerTeacherComponent.builder().build().injectA(this); } public void teacher() { student.startLessons(); } public static void main(String[] args) { new Teacher().teacher(); } }
看一下打印效果
Student create!!! 开始上课了
3,源码分析
ok,没什么问题,那我们现在只是停留在会用的阶段,底层我们的源码到底是怎么吧我们的对象创建出来的,还有怎么将我们的对象设置到需要它的地方呢,不要慌,老司机现在就带你来看看源码是什么实现的。这里的源码很简单,一共涉及到三个类,都是我们运行时生成的DaggerTeacherComponent、Teacher_MembersInjector、Student_Factory。
先来看看DaggerTeacherComponent,按照字面意思这是我们Teacher的桥梁类,源码如下:
package com.qianmo.rxjavatext; import dagger.MembersInjector; import javax.annotation.Generated; @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.github.io/dagger" ) public final class DaggerTeacherComponent implements TeacherComponent { private MembersInjector<Teacher> teacherMembersInjector; private DaggerTeacherComponent(Builder builder) { assert builder != null; initialize(builder); } public static Builder builder() { return new Builder(); } public static TeacherComponent create() { return builder().build(); } @SuppressWarnings("unchecked") private void initialize(final Builder builder) { this.teacherMembersInjector = Teacher_MembersInjector.create(Student_Factory.create()); } @Override public void injectA(Teacher teacher) { teacherMembersInjector.injectMembers(teacher); } public static final class Builder { private Builder() {} public TeacherComponent build() { return new DaggerTeacherComponent(this); } } }
我们首先来看我们之前的调用方法如下
DaggerTeacherComponent.builder().build().injectA(this);
首先看一下DaggerTeacherComponent.builder()方法,我们从源码中可以看到DaggerTeacherComponent.builder()调用生成了一个Builder 对象,我们继续代用builder.builder()方法,而我们的build类中代码如下(这里再次吐槽博客园的编辑器,在线编辑的时候无法显示引用代码的行号,这样我们就没法通过行号来解释每一行代码的意思,而必须要重写贴一次代码,操蛋!!!):
public static final class Builder { private Builder() {} public TeacherComponent build() { return new DaggerTeacherComponent(this); } }
“new DaggerTeacherComponent(this);” 看到没,实际上是调用我们的DaggerTeacherComponent对象,而我们的DaggerTeacherComponent构造函数是调用的initialize()方法,看一下方法里面具体代码
@SuppressWarnings("unchecked") private void initialize(final Builder builder) { this.teacherMembersInjector = Teacher_MembersInjector.create(Student_Factory.create()); }
这时候出现了Teacher_MembersInjector、Student_Factory类,我们先不要管,继续往下看,上面我们调用完builder.builder()方法方法之后,再调用injectA(this)的方法,具体代码如下:
@Override public void injectA(Teacher teacher) { teacherMembersInjector.injectMembers(teacher); }
呃,这里我们又看到Teacher_MembersInjector这个类对象了,所以这时候看看我们Teacher_MembersInjector的源码了,我们上面一共在两个地方使用了Teacher_MembersInjector,一个是.create方法,一个是injectMember方法,所以我们主要要留心源码里面这两个类,具体源码如下:
package com.qianmo.rxjavatext; import dagger.MembersInjector; import javax.annotation.Generated; import javax.inject.Provider; @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.github.io/dagger" ) public final class Teacher_MembersInjector implements MembersInjector<Teacher> { private final Provider<Student> studentProvider; public Teacher_MembersInjector(Provider<Student> studentProvider) { assert studentProvider != null; this.studentProvider = studentProvider; } public static MembersInjector<Teacher> create(Provider<Student> studentProvider) { return new Teacher_MembersInjector(studentProvider); } @Override public void injectMembers(Teacher instance) { if (instance == null) { throw new NullPointerException("Cannot inject members into a null reference"); } instance.student = studentProvider.get(); } public static void injectStudent(Teacher instance, Provider<Student> studentProvider) { instance.student = studentProvider.get(); } }