Qualifier
当同一个对象有多种注入方式,Dagger2怎么知道使用哪种方式注入呢?
因此需要用到@Qualifier表识的注解来限定,而@Name也是一种@Qualifier注解。因此提供的地方使用@Name方式如下:
@Module
public class SubModule {
@Named("aaa")
@ActivitySingleton
@Provides
public Logger providerLogger(Retrofit retrofit) {
System.out.println("aaaa");
return new Logger(retrofit);
}
@Named("bbb")
@ActivitySingleton
@Provides
public Logger providerLoggerB(Retrofit retrofit) {
System.out.println("bbbb");
return new Logger(retrofit);
}
}
使用不同的方式注入的代码如下:
@Inject
@Named("aaa")
Logger logger;
@Inject
@Named("bbb")
Logger logger2;
在使用@Named("")的地方也可以换成自定义Qualifier注解
例如
@Qualifier
@Documented
@Retention(RUNTIME)
public @interface AAAA {
}
//BBB省略...
则Module中代码如下:
@Module
public class SubModule {
@AAA
@ActivitySingleton
@Provides
public Logger providerLogger(Retrofit retrofit) {
System.out.println("aaaa");
return new Logger(retrofit);
}
@BBB
@ActivitySingleton
@Provides
public Logger providerLoggerB(Retrofit retrofit) {
System.out.println("bbbb");
return new Logger(retrofit);
}
}
使用的地方注解也修改成@AAA、@BBB即可。
Lazy
Dagger2可以使用懒加载,当Lazy<T> 等同于注入T,只是生成T的时间在调用lazy.get()时,且多次调用get方法,返回的是同一个对象T。例如延时获取Logger的代码如下:
public class Street {
@Inject
@AAA
Logger logger;
@Inject
@BBB
Lazy<Logger> logger2;
public Street() {
}
public void byCoffee() {
AppComponent netComponent = AppManager.getAppComponent();
CoffeeShopComponent coffeeShopComponent = netComponent.getCoffeeShopComponentBuilder().build();
coffeeShopComponent.inject(this);
logger.log("inject success");
logger2.get().log("inject success 2");
}
}
lazy是一种对注入对象的包装,还有一种对注入对象的包装是Provider<T>,看一下CoffeeShopComponent的实现,可以发现里面就用到了Provider<T>,代码如下
private final class CoffeeShopComponentImpl implements CoffeeShopComponent {
private Provider<Logger> providerLoggerProvider;
private Provider<Logger> providerLoggerBProvider;
private CoffeeShopComponentImpl(SubModule subModuleParam) {
initialize(subModuleParam);
}
@SuppressWarnings("unchecked")
private void initialize(final SubModule subModuleParam) {
this.providerLoggerProvider = DoubleCheck.provider(SubModule_ProviderLoggerFactory.create(subModuleParam, DaggerAppComponent.this.providerRetrofitProvider));
this.providerLoggerBProvider = DoubleCheck.provider(SubModule_ProviderLoggerBFactory.create(subModuleParam, DaggerAppComponent.this.providerRetrofitProvider));
}
@Override
public void inject(Street street) {
injectStreet(street);}
private Street injectStreet(Street instance) {
Street_MembersInjector.injectLogger(instance, providerLoggerProvider.get());
Street_MembersInjector.injectLogger2(instance, DoubleCheck.lazy(providerLoggerBProvider));
return instance;
}
}
Provider<T>.get() 方法会强制调用生成T,具体如何生成有Module中定义决定。多次调用等同于定义了多个注入对象,因此多次调用是否会返回相同的对象,等同于多个变量是否是相等的,也就是取决于该注入对象是否在Component实例内是单例的。Provider<T>使用方式如下:
public class Street {
@Inject
@AAA
Logger logger;
@Inject
@BBB
Provider<Logger> logger2;
public Street() {
}
public void byCoffee() {
AppComponent netComponent = AppManager.getAppComponent();
CoffeeShopComponent coffeeShopComponent = netComponent.getCoffeeShopComponentBuilder().build();
coffeeShopComponent.inject(this);
logger.log("inject success,get1:"+logger2.get().hashCode()+" ge2:"+logger2.get().hashCode());
}
}
logger2.get()多次调用是否返回同一对象取决于Module中限定@BBB的提供方式是否是单例的。
单例:
@BBB
@ActivitySingleton
@Provides
public Logger providerLoggerB(Retrofit retrofit) {
System.out.println("bbbb");
return new Logger(retrofit);
}
非单例:
@BBB
//@ActivitySingleton
@Provides
public Logger providerLoggerB(Retrofit retrofit) {
System.out.println("bbbb");
return new Logger(retrofit);
}
网友评论