代碼示例
class Tiger {
String name;
public Tiger(String name) {
this.name = name;
}
public Tiger() {
}
public void sleep() {
System.out.println("Tiger sleeping");
}
}
// 自定義Qualifier註解
@Qualifier
public @interface Tiger1 {
}
// 自定義Qualifier註解
@Qualifier
public @interface Tiger2 {
}
@Module
class ZooModule {
// 使用自定義Qualifier註解
@Tiger1
@Provides
public Tiger providerTiger_1() {
return new Tiger();
}
@Tiger2
@Provides
public Tiger providerTiger_2() {
return new Tiger("米飯");
}
}
@Component(modules = {ZooModule.class})
interface ZooComponent {
Zoo inject(Zoo zoo);
}
public class Zoo {
// 使用自定義Qualifier註解,用以區分tiger1到底使用注射器中的哪個對象.
@Tiger1
@Inject
Tiger tiger1;
@Tiger2
@Inject
Tiger tiger2;
@Test
public void 案例九() {
DaggerZooComponent.create().inject(this);
tiger1.sleep();
tiger2.sleep();
}
}
Dagger2生成代碼閱讀
主要分析當同一個注射器中存在兩個相同類型的對象,容器中需要使用這兩個對象的時候該如何區分.
就着上面的案例來看下Degger2生成的代碼,生成的代碼在build\generated\sources\annotationProcessor\..
文件夾中.
- 當調用
.inject(this)
時,最終調用的代碼如下:
final class DaggerZooComponent implements ZooComponent {
@Override
public Zoo inject(Zoo zoo) {
return injectZoo(zoo);
}
private Zoo injectZoo(Zoo instance) {
// ZooModule_ProviderTiger_1Factory.providerTiger_1(zooModule): 通過ZooModule中的providerTiger_1()方法獲取tiager對象
// ZooModule_ProviderTiger_2Factory.providerTiger_2(zooModule): 通過ZooModule中的providerTiger_2()方法獲取tiager對象
Zoo_MembersInjector.injectTiger1(instance, ZooModule_ProviderTiger_1Factory.providerTiger_1(zooModule));
Zoo_MembersInjector.injectTiger2(instance, ZooModule_ProviderTiger_2Factory.providerTiger_2(zooModule));
return instance;
}
}
上面的很常規的代碼,唯一的區別在於爲容器中字段賦值tiger
對象時,分別調用了兩個不同的方法
public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
@InjectedFieldSignature("com.yey.dagger2.Zoo.tiger1")
@Tiger1 // 這是案例中定義的註解
public static void injectTiger1(Zoo instance, Object tiger1) {
instance.tiger1 = (Tiger) tiger1;// 容器中tiger1字段賦值爲providerTiger_1()返回的對象
}
@InjectedFieldSignature("com.yey.dagger2.Zoo.tiger2")
@Tiger2
public static void injectTiger2(Zoo instance, Object tiger2) {
instance.tiger2 = (Tiger) tiger2;// 容器中tiger2字段賦值爲providerTiger_2()返回的對象
}
}
當注射器中存在多個相同類型對象時候,自定義@Qualifier
註解能夠幫助容器獲取特定的對象,另外如果注射器中存在多個相同類型的對象,Dagger2會報錯重複綁定.