Dagger2主要有如下几个核心概念:
@Component
@Module
@Inject
@Singleton
很多同学在学习Dagger2时都知道如何使用,但可能知其然而不知其所以然,本文以Dagger2官方例子,通过分析生成后代码,帮助大家加深对上述概念的理解:
CoffeeShop.java
@Singleton
@Component(modules = {DripCoffeeModule .class})
public interface CoffeeShop {
void inject(MyApplication application);
}
DripCoffeeModule.java
@Module
public class DripCoffeeModule {
@Provides
Heater provideHeater() {
return new ElectricHeater();
}
@Provides
Pump providePump(Thermosiphon pump) {
return pump;
}
}
CoffeeShop.java编译生成DaggerCoffeeShop.java,代码比较冗长读者可以不需要细看,主要包含成员变量,initialize方法,Builder类三部分。
public final class DaggerCoffeeShop implements CoffeeShop {
private MembersInjector myApplicationMembersInjector;
private Provider provideHeaterProvider;
private Provider thermosiphonProvider;
private Provider providePumpProvider;
private MembersInjector coffeeMakerMembersInjector;
private Provider coffeeMakerProvider;
private DaggerCoffeeShop(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static CoffeeShop create() {
return new Builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.myApplicationMembersInjector =
MyApplication_MembersInjector.create(dispatchingAndroidInjectorProvider);
this.provideHeaterProvider =
DripCoffeeModule_ProvideHeaterFactory.create(builder.dripCoffeeModule);
this.thermosiphonProvider =
DoubleCheck.provider(Thermosiphon_Factory.create(provideHeaterProvider));
this.providePumpProvider =
DripCoffeeModule_ProvidePumpFactory.create(builder.dripCoffeeModule, thermosiphonProvider);
this.coffeeMakerMembersInjector =
CoffeeMaker_MembersInjector.create(provideHeaterProvider, providePumpProvider);
this.coffeeMakerProvider =
DoubleCheck.provider(
CoffeeMaker_Factory.create(
coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));
}
@Override
public void inject(MyApplication application) {
myApplicationMembersInjector.injectMembers(application);
}
public static final class Builder {
private DripCoffeeModule dripCoffeeModule;
private Builder() {}
public CoffeeShop build() {
if (dripCoffeeModule == null) {
this.dripCoffeeModule = new DripCoffeeModule();
}
return new DaggerCoffeeShop(this);
}
public Builder dripCoffeeModule(DripCoffeeModule dripCoffeeModule) {
this.dripCoffeeModule = Preconditions.checkNotNull(dripCoffeeModule);
return this;
}
}
从上述生成的代码看,我们可以知道
- Component从module加载生成所有的创建对象的Factory create mehod。
private Provider provideHeaterProvider;
this.provideHeaterProvider =
DripCoffeeModule_ProvideHeaterFactory.create(builder.dripCoffeeModule);
this.thermosiphonProvider =
DoubleCheck.provider(Thermosiphon_Factory.create(provideHeaterProvider));
2.如果标记为@Singleton,则会生成DoubleCheck.provider()保证创建为单例模式
this.coffeeMakerProvider =
DoubleCheck.provider(
CoffeeMaker_Factory.create(
coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));
3.内部类Builder负责创建component依赖的所有Module
public static final class Builder {
private DripCoffeeModule dripCoffeeModule;
private Builder() {}
public CoffeeShop build() {
if (dripCoffeeModule == null) {
this.dripCoffeeModule = new DripCoffeeModule();
}
return new DaggerCoffeeShop(this);
}
public Builder dripCoffeeModule(DripCoffeeModule dripCoffeeModule) {
this.dripCoffeeModule = Preconditions.checkNotNull(dripCoffeeModule);
return this;
}
}
4.如果对构造函数标记为@Inject,则会自动生成MembersInjector类
CoffeeMaker.java
@Singleton
public class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
@Inject
public CoffeeMaker(Heater heater, Pump pump) {
Log.i("wenson", "CoffeeMake create");
this.heater = heater;
this.pump = pump;
}
public void brew(){
}
}
Component类生成对应的方法,其中包含CoffeeMaker_MembersInjector 和 CoffeeMaker_Factory这2个负责实际创建的类。
private MembersInjector coffeeMakerMembersInjector;
this.coffeeMakerMembersInjector =
CoffeeMaker_MembersInjector.create(provideHeaterProvider, providePumpProvider);
this.coffeeMakerProvider =
DoubleCheck.provider(
CoffeeMaker_Factory.create(
coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));
查看生成的CoffeeMaker_MembersInjector类, 这个类负责对象的具体创建
public final class CoffeeMaker_MembersInjector implements MembersInjector {
private final Provider heaterProvider;
private final Provider pumpProvider;
public CoffeeMaker_MembersInjector(Provider heaterProvider, Provider pumpProvider) {
assert heaterProvider != null;
this.heaterProvider = heaterProvider;
assert pumpProvider != null;
this.pumpProvider = pumpProvider;
}
public static MembersInjector create(
Provider heaterProvider, Provider pumpProvider) {
return new CoffeeMaker_MembersInjector(heaterProvider, pumpProvider);
}
@Override
public void injectMembers(CoffeeMaker instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.heater = heaterProvider.get();
instance.pump = pumpProvider.get();
}
public static void injectHeater(CoffeeMaker instance, Provider heaterProvider) {
instance.heater = heaterProvider.get();
}
public static void injectPump(CoffeeMaker instance, Provider pumpProvider) {
instance.pump = pumpProvider.get();
}
}
查看生成的CoffeeMaker_Factory类,主要负责对象创建的再封装
public final class CoffeeMaker_Factory implements Factory {
private final MembersInjector coffeeMakerMembersInjector;
private final Provider heaterProvider;
private final Provider pumpProvider;
public CoffeeMaker_Factory(
MembersInjector coffeeMakerMembersInjector,
Provider heaterProvider,
Provider pumpProvider) {
assert coffeeMakerMembersInjector != null;
this.coffeeMakerMembersInjector = coffeeMakerMembersInjector;
assert heaterProvider != null;
this.heaterProvider = heaterProvider;
assert pumpProvider != null;
this.pumpProvider = pumpProvider;
}
@Override
public CoffeeMaker get() {
return MembersInjectors.injectMembers(
coffeeMakerMembersInjector, new CoffeeMaker(heaterProvider.get(), pumpProvider.get()));
}
public static Factory create(
MembersInjector coffeeMakerMembersInjector,
Provider heaterProvider,
Provider pumpProvider) {
return new CoffeeMaker_Factory(coffeeMakerMembersInjector, heaterProvider, pumpProvider);
}
}
总结:
Dagger的优点是是编译期静态生成对象依赖注入的所有代码,不是运行时动态反射方式。
优点是运行时无性能副作用,缺点是编译后生成大量类,对象注入需要指定类,生成对应的类方法。
即使使用google的AndroidInjector, 也只是方便开发人员少写一部分代码。
从以上代码分析可以帮助我们更深刻得理解Component和Module的概念。
打个比方:Component类似注射器,Module是连接注射器的各个原料工厂。
我们可以定义各种原料工厂(Module), 有网络的NetModule(Retrofit),有存储的DBModule(Room)等等。
看上述代码很累的同学,建议将Dagger2官方例子导入到工程里实际编译阅读,方便理解。