前言
之前介绍了最简单的注入生成代码,使用的注入方式是使用@Inject
, 今天我们解析另外一种注入方式。
之前关于@Inject的分析:
Dagger2 分析【1】
该章节主要分析使用@Module来注入的情况
Module
使用@Inject标注构造函数来提供依赖的对象实例的方法,不是万能的,在以下几种场景中无法使用:
- 第三方库的类不能被标注
- 构造函数中的参数必须配置
- 抽象的类
所以这里我们先简单的使用Module:
@Module
public class CarModule {
@Provides
Car carProvide(Engine engine) {
return new Car(engine);
}
}
当然Component也需要跟着做一些调整:
@Component(modules = CarModule.class)
public interface ManComponent {
void inject(ManActivity mainActivity);
}
接着我们来分析生成的代码,这里最大的不同就是XXModule中有几个@Provides,就会生成几个对应的类:XXModule_ProvideYYFactory
因为这里我们只有一个@Provides,所以就生成了一个CarModule_ProvideCarFactory:
public final class CarModule_CarProvideFactory implements Factory<Car> {
private final CarModule module;
private final Provider<Engine> engineProvider;
public CarModule_CarProvideFactory(CarModule module, Provider<Engine> engineProvider) {
assert module != null;
this.module = module;
assert engineProvider != null;
this.engineProvider = engineProvider;
}
@Override
public Car get() {
return Preconditions.checkNotNull(
module.carProvide(engineProvider.get()),
"Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<Car> create(CarModule module, Provider<Engine> engineProvider) {
return new CarModule_CarProvideFactory(module, engineProvider);
}
/** Proxies {@link CarModule#carProvide(Engine)}. */
public static Car proxyCarProvide(CarModule instance, Engine engine) {
return instance.carProvide(engine);
}
}
同样这个类也是实现了Factory<T>
接口,不同于上一节的Car_Factory,这个类中多了一个构造方法和一个proxyProvideCar
方法,同时get
方法的实现也有了一点不一样。
原来的get()
是直接调用了构造函数来返回实例的,而现在是通过module.carProvide来获取的实例, 这正是@Proxies起的作用。
proxyCarProvide
所起的作用和get
的作用一样。
还有一种比较特殊的情况,就是我们自己重载了XXModule的构造方法,给它加上了几个参数。
这时会发现,DaggerXXXComponent中就没有了create()
方法。 这是因为Builder
类中,已经无法自己构造出XXModule了,需要通过外部传入XXModule。
所以在这种情况下,就只有使用
DaggerXXXComponent.builder().XXModule(new XXModule()).build().inject();
需要注意的是,如果这里的注入涉及到了某个Module,同时该Module的构造方法是需要参数的,那么就必须传入。
小结
在使用@Module的时候,里面会有对应的@Providers来提供需要生成的对象。
每一个@Provides,都会生成对应的XXModule_ProvideYYFactory, 该类就类似于最基础的Factory<T>,用于提供实例。