代碼示例
class Food {
}
class Tiger {
// 假如老虎需要食物
Food food;
public Tiger(Food food) {
this.food = food;
}
public void sleep() {
System.out.println("Tiger sleeping");
}
}
// 爲注射器提供工廠類
// @Module: 表示Dagger2可以將該類當作對象工廠.
@Module
class ZooModule {
private Food food;
public ZooModule(Food food) {
this.food = food;
}
// @Provides: 表示Dagger2可以調用providerTiger(Food food)方法爲注射器提供對象.
@Provides
public Tiger providerTiger() {
return new Tiger(food);
}
}
// 對象使用者
public class Zoo {
// @Inject: 該註解用於成員變量上代表注射器可以爲該成員變量賦值對象.
@Inject
Tiger tiger;
@Test
public void 案例六() {
// ZooModule中的成員food無法通過Dagger2自動生成,需要用戶手動創建.
DaggerZooComponent.builder().zooModule(new ZooModule(new Food())).build().inject(this);
tiger.sleep();
}
}
// 注射器
// @Component: 該註解是用來創造對象提供方和對象使用間的橋樑,如何將對象賦值給使用者的成員變量都是由它來做的.
@Component(modules = {ZooModule.class})
interface ZooComponent {
Zoo inject(Zoo zoo);
}
Dagger2生成代碼閱讀
主要分析Module中依賴某個無法使用Dagger2創建的對象,該如何將該對象加入注射器中?
類似情況很常見,比如Activity由系統創建,假如某個Module依賴Activity對象,那Dagger2如何處理它們的依賴關係.
就着上面的案例來看下Degger2生成的代碼,生成的代碼在build\generated\sources\annotationProcessor\..
文件夾中.
DaggerZooComponent.builder().zooModule(new ZooModule(new Food())).build()
創建DaggerZooComponent
對象,這裏主要看下zooModule(new ZooModule(new Food()))
如何處理的.
final class DaggerZooComponent implements ZooComponent {
// 工廠對象
private final ZooModule zooModule;
// DaggerZooComponent構造方法
private DaggerZooComponent(ZooModule zooModuleParam) {
this.zooModule = zooModuleParam;
}
public static Builder builder() {
// 創建DaggerZooComponent.Builder對象
return new Builder();
}
static final class Builder {
private ZooModule zooModule;
private Builder() {
}
// 創建ZooModule對象
public Builder zooModule(ZooModule zooModule) {
this.zooModule = Preconditions.checkNotNull(zooModule);
return this;
}
public ZooComponent build() {
Preconditions.checkBuilderRequirement(zooModule, ZooModule.class);
// 創建DaggerZooComponent對象,它持有ZooModule引用
return new DaggerZooComponent(zooModule);
}
}
}
.inject(this)
對象注入
使用DaggerZooComponent
對象將Dagger2
創建的Tiger
對象注入到Zoo
中.
final class DaggerZooComponent implements ZooComponent {
// 接口中的方法,由DaggerZooComponent實現,該方法就是用來向Zoo對象中注入Tiger對象的.
@Override
public Zoo inject(Zoo zoo) {
// zoo就是inject(this)中的this了,代表Zoo對象.
return injectZoo(zoo);
}
private Zoo injectZoo(Zoo instance) {
// 1. ZooModule_ProviderTigerFactory.providerTiger(zooModule): 通過ZooModule工廠獲取Zoo需要的Tiger對象.
// 2. Zoo_MembersInjector.injectTiger(instance, getTiger()): 這裏就是爲Zoo對象中所需字段賦值.
Zoo_MembersInjector.injectTiger(instance, ZooModule_ProviderTigerFactory.providerTiger(zooModule));
return instance;
}
}
ZooModule_ProviderTigerFactory.providerTiger(zooModule)
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
public static Tiger providerTiger(ZooModule instance) {
// providerTiger()爲用戶在ZooModule中實現的方法,用來返回Tiger對象.
return Preconditions.checkNotNull(instance.providerTiger(), "Cannot return null from a non-@Nullable @Provides method");
}
}
- 賦值
Zoo_MembersInjector.injectTiger(instance, ZooModule_ProviderTigerFactory.providerTiger(zooModule));
public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
public static void injectTiger(Zoo instance, Object tiger) {
instance.tiger = (Tiger) tiger;
}
}
如果Foot
無法通過Dagger2
自行創建加入注射器中的話,可以用戶手動創建一個Foot
對象,再通過Module
構造將該對象傳入Module
中,然後交給Module
工廠方法使用.