想学一下dagger2的源码解析,网上搜索一下看到有很多,个人感觉也仅仅是生成后的代码解析。我也写过一篇关于dagger2的用法,用法步骤还是挺多的。具体在这里
开始
先看两个图左边是编写的annotation
、bean
、component
、module
,右边是生成的代码文件,bean
包里是Factory、component
包里是各个scope的组件给提供给Activity或者其他地方使用的、module
包是用来提供对象的工厂、MainActivity_MembersInjector
是用来专门注入成员变量的
implementation 'com.google.dagger:dagger:2.14.1'
annotationProcessor "com.google.dagger:dagger-compiler:2.14.1"
Application
public class DApplication extends Application {
public static DApplication app;
AppComponent applicationComponent;
@Override
public void onCreate() {
super.onCreate();
app = this;
applicationComponent = DaggerAppComponent
.builder()
.appModule(new AppModule())
.build();
}
public static DApplication getInstance(){
return app;
}
}
这是我写在Application中的代码
定义了static暴露给外部使用
AppComponent applicationComponent;定义了
Application的
component(组件)`
1、DaggerAppComponent.builder()
重点是下面,看Builder就是一个建造者模式, DaggerAppComponent
的内容,这个类位于build-generated-source-apt-debug-你的包名
里面,或者Ctrl点这个类
public final class DaggerAppComponent implements AppComponent {
//省略部分代码
@Override
public School getSchool() {
return provideSchoolProvider.get();
}
}
这个类继承了我们定义的AppComponent
接口,定义了一个未完成的方法,这个生成的类帮我们去完成了这个方法
DaggerAppComponent.builder()
这里面什么都没干只是new了一个Builder
2、.appModule(new AppModule())
public Builder appModule(AppModule appModule) {
this.appModule = Preconditions.checkNotNull(appModule);
return this;
}
这里面判空,赋值,返回
2、.build();
public AppComponent build() {
if (appModule == null) {
this.appModule = new AppModule();
}
return new DaggerAppComponent(this);
}
判空,new出了AppModule,点进去就知道,这是我们自己提供给自己,以后可能需要 被注入对象 的注入方法,说的有点绕
直白的说就 在未来代码的某个地方,我们定义了一个变量(未赋值的),但是我们需要给他赋值,则会用这里的方法去给他赋值。这里我只是new School();
也可以是反射、动态代理、甚至是clone、反序列化。
最后build()
的时候也帮我们初始化了AppModule
所以我们不一定要用上面的方法进行.appModule(new AppModule())
最后交给本类DaggerAppComponent
初始化
private void initialize(final Builder builder) {
this.provideSchoolProvider =
DoubleCheck.provider(AppModule_ProvideSchoolFactory.create(builder.appModule));
}
AppModule_ProvideSchoolFactory.create
里面new了自己,赋值appModule
,返回 App模块 提供School的工厂
DoubleCheck.provider(..)
这里面也是判断空返回DoubleCheck
对象,里面有个T get()
方法,看类名和内容就是一个双重锁返回我们需要的对象。
这时Application就初始化好了
MainActivity
DaggerActivityComponent.builder()
.appComponent(DApplication.getInstance().applicationComponent)
.activityModule(new ActivityModule())
.build()
.inject(this);
老样子还是建造者
public static final class Builder {
private Builder() {}
public ActivityComponent build() {
if (activityModule == null) {
this.activityModule = new ActivityModule();
}
if (appComponent == null) {
throw new IllegalStateException(AppComponent.class.getCanonicalName() + " must be set");
}
return new DaggerActivityComponent(this);
}
//下面两个提供给外部构造的方法
public Builder activityModule(ActivityModule activityModule) {
this.activityModule = Preconditions.checkNotNull(activityModule);
return this;
}
public Builder appComponent(AppComponent appComponent) {
this.appComponent = Preconditions.checkNotNull(appComponent);
return this;
}
}
build()
方法看必须传一个 appComponent
, 这里 传入了DApplication.getInstance().applicationComponent
1、new DaggerActivityComponent(this);
private void initialize(final Builder builder) {
this.provideStuProvider =
DoubleCheck.provider(ActivityModule_provideStuFactory.create(buil de r.activityModule));
this.appComponent = builder.appComponent;
}
这里还是和Application中初始化一样,创建了一个ActivityModule_provideStuFactory
对象里面赋值。Activity模块 提供Stu的工厂
用DoubleCheck<T>(delegate)
去代理这个类,也就是用这个类 去 提供
注入对象
到最外面把 DoubleCheck
赋值给了 provideStuProvider
2、.inject(this);
public final class DaggerActivityComponent implements ActivityComponent {
@Override
public void inject(MainActivity testActivity) {
injectMainActivity(testActivity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectStu1(instance,provideStuProvider.get());
MainActivity_MembersInjector.injectStu2(instance,provideStuProvider.get());
MainActivity_MembersInjector.injectSchool(
instance,
Preconditions.checkNotNull(
appComponent.getSchool(), "Cannot return null from a non-@Nullable component method"));
return instance;
}
}
关键的在这里
调用了MainActivity_MembersInjector的静态方法,塞入了Activity和从工厂提供的对象
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
//省去部分代码
public static void injectStu1(MainActivity instance, Student stu1) {
instance.stu1 = stu1;
}
}
由于School是全局范围的所以,使用了传入的appComponent
给出对象,在MainActivity初始化的时候,初始化的时候使用了Application的 AppComponent applicationComponent
到这里已经会使用 在全局范围使用同一个对象 和 在Activity中使用同一个对象
构造函数 注入对象
我增加了一个Teacher类 和 修改了 ActivityModule、类,为了注入一个类,需要传入另一个类的对象
public class Teacher {
String t_name;
@Inject
public Teacher(){
}
}
public class Student {
Teacher teacher;
@Inject
public Student(Teacher t) {
teacher = t;
}
public Teacher getTeacher() {
return teacher;
}
}
@Module
public class ActivityModule {
@ActivityScope
@Provides
Student provideStu(Teacher t){
return new Student(t);
}
//这里没有ActivityScope 没有标记 在Activity范围
@Provides
Teacher provideTeacher(){
return new Teacher();
}
}
编译后增加了Teacher_Factory
、ActivityModule_provideTeacherFactory
类
主要是ActivityModule_provideStuFactory
提供stu的Factory
@Override
public Student get() {
return Preconditions.checkNotNull(
module.provideStu(tProvider.get()),
"Cannot return null from a non-@Nullable @Provides method");
}
这里module
是ActivityModule
,去调用 ActivityModule
的provideStu
(这是我定义的)
在MainActivity中增加
@Inject
Teacher teacher1;
编译后 DaggerActivityComponent会增加 给这个对象注入的方法
public final class DaggerActivityComponent implements ActivityComponent {
private MainActivity injectMainActivity(MainActivity instance) {
//移除部分代码
MainActivity_MembersInjector.injectTeacher1(
instance,ActivityModule_ProvideTeacherFactory.proxyProvideTeacher(acti vityModu le));
}
}
因为ActivityModule
中 provideTeacher()
没有任何范围所以每次注入都是不同的对象,也就会调用代理方法proxyProvideTeacher
也就是我们提供的new Teacher()
根据代码内容简单的画了一个图方便理解
到这里 也基本结束了不过我还有一个问题,每一个需要注入的类 都会生成一个Factory,比如Student_Factory,全局搜索之后貌似没有看到具体引用的地方,只有本身有个static方法,搜索这个方法也没有具体使用的地方,如果有大佬看到这里,希望能指点一二。
学艺不精,如果内容有错误请及时联系我,我及时改正