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