想學(xué)一下dagger2的源碼解析服猪,網(wǎng)上搜索一下看到有很多饼拍,個(gè)人感覺也僅僅是生成后的代碼解析。我也寫過一篇關(guān)于dagger2的用法哈误,用法步驟還是挺多的哩至。具體在這里
開始
先看兩個(gè)圖左邊是編寫的annotation
躏嚎、bean
、component
菩貌、module
卢佣,右邊是生成的代碼文件,bean
包里是Factory箭阶、component
包里是各個(gè)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()
重點(diǎn)是下面嘹叫,看Builder就是一個(gè)建造者模式, DaggerAppComponent
的內(nèi)容诈乒,這個(gè)類位于build-generated-source-apt-debug-你的包名
里面罩扇,或者Ctrl點(diǎn)這個(gè)類
public final class DaggerAppComponent implements AppComponent {
//省略部分代碼
@Override
public School getSchool() {
return provideSchoolProvider.get();
}
}
這個(gè)類繼承了我們定義的AppComponent
接口,定義了一個(gè)未完成的方法怕磨,這個(gè)生成的類幫我們?nèi)ネ瓿闪诉@個(gè)方法
DaggerAppComponent.builder()
這里面什么都沒干只是new了一個(gè)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,點(diǎn)進(jìn)去就知道导饲,這是我們自己提供給自己捞高,以后可能需要 被注入對象 的注入方法,說的有點(diǎn)繞
直白的說就 在未來代碼的某個(gè)地方渣锦,我們定義了一個(gè)變量(未賦值的)硝岗,但是我們需要給他賦值,則會用這里的方法去給他賦值泡挺。這里我只是new School();
也可以是反射辈讶、動態(tài)代理、甚至是clone娄猫、反序列化贱除。
最后build()
的時(shí)候也幫我們初始化了AppModule
所以我們不一定要用上面的方法進(jìn)行.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
對象,里面有個(gè)T get()
方法月幌,看類名和內(nèi)容就是一個(gè)雙重鎖返回我們需要的對象。
這時(shí)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);
}
//下面兩個(gè)提供給外部構(gòu)造的方法
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()
方法看必須傳一個(gè) 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中初始化一樣扯躺,創(chuàng)建了一個(gè)ActivityModule_provideStuFactory
對象里面賦值。Activity模塊 提供Stu的工廠
用DoubleCheck<T>(delegate)
去代理這個(gè)類,也就是用這個(gè)類 去 提供
注入對象
到最外面把 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;
}
}
關(guān)鍵的在這里
調(diào)用了MainActivity_MembersInjector的靜態(tài)方法倍啥,塞入了Activity和從工廠提供的對象
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
//省去部分代碼
public static void injectStu1(MainActivity instance, Student stu1) {
instance.stu1 = stu1;
}
}
由于School是全局范圍的所以,使用了傳入的appComponent
給出對象澎埠,在MainActivity初始化的時(shí)候虽缕,初始化的時(shí)候使用了Application的 AppComponent applicationComponent
到這里已經(jīng)會使用 在全局范圍使用同一個(gè)對象 和 在Activity中使用同一個(gè)對象
構(gòu)造函數(shù) 注入對象
我增加了一個(gè)Teacher類 和 修改了 ActivityModule、類蒲稳,為了注入一個(gè)類氮趋,需要傳入另一個(gè)類的對象
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 沒有標(biāo)記 在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
江耀,去調(diào)用 ActivityModule
的provideStu
(這是我定義的)
在MainActivity中增加
@Inject
Teacher teacher1;
編譯后 DaggerActivityComponent會增加 給這個(gè)對象注入的方法
public final class DaggerActivityComponent implements ActivityComponent {
private MainActivity injectMainActivity(MainActivity instance) {
//移除部分代碼
MainActivity_MembersInjector.injectTeacher1(
instance,ActivityModule_ProvideTeacherFactory.proxyProvideTeacher(acti vityModu le));
}
}
因?yàn)?code>ActivityModule 中 provideTeacher()
沒有任何范圍所以每次注入都是不同的對象剩胁,也就會調(diào)用代理方法proxyProvideTeacher
也就是我們提供的new Teacher()
根據(jù)代碼內(nèi)容簡單的畫了一個(gè)圖方便理解
到這里 也基本結(jié)束了不過我還有一個(gè)問題,每一個(gè)需要注入的類 都會生成一個(gè)Factory祥国,比如Student_Factory昵观,全局搜索之后貌似沒有看到具體引用的地方,只有本身有個(gè)static方法舌稀,搜索這個(gè)方法也沒有具體使用的地方索昂,如果有大佬看到這里,希望能指點(diǎn)一二扩借。
學(xué)藝不精,如果內(nèi)容有錯(cuò)誤請及時(shí)聯(lián)系我缤至,我及時(shí)改正