Dagger2入门系列二:Module&Component源码分析

0、相关文章:

参考此文:Android 神兵利器Dagger2使用详解(二)Module&Component源码分析

在我的上一篇文章中,我们通过Dagger2依赖注入的两种方式获取Student对象,并简单了解了各个组件的作用和互相的联系:

@Inject : 注入,被注解的构造方法会自动编译生成一个Factory工厂类提供该类对象。

@Component: 注入器,类似快递员,作用是将产生的对象注入到需要对象的容器中,供容器使用。

@Module: 模块,类似快递箱子,在Component接口中通过@Component(modules =
xxxx.class),将容器需要的商品封装起来,统一交给快递员(Component),让快递员统一送到目标容器中。

本文我们继续按照上文案例来讲,通过源码分析,看看究竟是为什么,我们能够仅仅通过数个注解,就能随心所欲使用Student对象。

1、代码回顾

我们先不考虑Module,还是这样的代码:

1.1、Student类

public class Student {

    @Inject
    public Student() {
    }

}

1.2、Module类

@Module
public class Test1Module {
    private Test1Activity activity;

    Test1Module(Test1Activity activity) {
        this.activity = activity;
    }

}

1.3、Component类

@Component(modules = Test1Module.class)
public interface Test1Component {
    void inject(Test1Activity activity);
}

1.4、Activity类

public class Test1Activity extends AppCompatActivity {

    @Inject
    Student student;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test1);
        ButterKnife.bind(this);
        initDatas();
    }

    private void initDatas() {
        DaggerTest1Component.builder()
//                .test1Module(new Test1Module(this))
                .build()
                .inject(this);
    }

    @OnClick(R.id.btn1)
    public void onViewClicked() {
        Toast.makeText(this, student.toString(), Toast.LENGTH_SHORT).show();
    }
}

2、源码解析

打开目录结构:

我们不难发现,编译器已经帮我们生成了这样几个文件:

  • Student_Factory
  • DaggerTest1Component
  • Test1Activity_MembersInjector
  • Test1Activity_ViewBinding(不用管,butterknife)

我们一一进行分析:

2.1、Student_Factory

上一篇文章我们已经进行了分析,很简单,当我们@Inject注解一个类的构造方法时,编译器会自动帮我们生成一个工厂类,负责生产该类的对象,类似于商品的厂家

package com.gs.dagtest1.bean;

import dagger.internal.Factory;

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();
  }
}

2.2、DaggerTest1Component

public final class DaggerTest1Component implements Test1Component {
  private DaggerTest1Component(Builder builder) {}

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

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

  @Override
  public void inject(Test1Activity activity) {
    injectTest1Activity(activity);
  }

  private Test1Activity injectTest1Activity(Test1Activity instance) {
    Test1Activity_MembersInjector.injectStudent(instance, new Student());
    return instance;
  }

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

    public Test1Component build() {
      return new DaggerTest1Component(this);
    }

    /**
     * @deprecated This module is declared, but an instance is not used in the component. This
     *     method is a no-op. For more, see https://google.github.io/dagger/unused-modules.
     */
    @Deprecated
    public Builder test1Module(Test1Module test1Module) {
      Preconditions.checkNotNull(test1Module);
      return this;
    }
  }
}

 

2.3、Test1Activity_MembersInjector

public final class Test1Activity_MembersInjector implements MembersInjector<Test1Activity> {
  private final Provider<Student> studentProvider;

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

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

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

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

很熟悉,我们在Activity中就用到了这个生成的类,编译器起名方式也很简洁:Dagger+你的Component接口名。

在我们的Activity中我们是这样使用:

DaggerTest1Component.builder()
//                .test1Module(new Test1Module(this))
                .build()
                .inject(this);

我们根据这个步骤查看源码,发现

DaggerTest1Component.builder().build()

实际上是通过建造者模式创建了一个新的DaggerTest1Component对象而已。

然后通过调用

  DaggerTest1Component.java
  DaggerTest1Component.builder().build().inject(this);

  @Override
  public void inject(Test1Activity activity) {
    injectTest1Activity(activity);
  }
  
  
  private Test1Activity injectTest1Activity(Test1Activity instance) {
    Test1Activity_MembersInjector.injectStudent(instance, new Student());
    return instance;
  }

  Test1Activity_MembersInjector.java
  public static void injectStudent(Test1Activity instance, Student student) {
    instance.student = student;
  }

可以看到这些代码最终是把activity对象和student对象都 传入到了Test1Activity_MembersInjector的injectStudent()方法中。

2.4、Test1Activity_MembersInjector类,将Student和Activity进行连接

public final class Test1Activity_MembersInjector implements MembersInjector<Test1Activity> {
  private final Provider<Student> studentProvider;

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

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

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

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

其实已经很简单了,在该Injector的injectMembers()方法中,已经将Student对象通过Student_Factory的get()方法获得,然后直接赋值给Activity的student对象了!

而create() 方法中传入的参数 Provider<Student> 就是Student_Factory工厂类。

public final class Student_Factory implements Factory<Student> {
 
}

public interface Factory<T> extends Provider<T> {

}

很明显了,Student_Factory是 Factory的实现类,Factory父类是Provider,向上转型嘛。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值