下面主要分析,Dagger 中使用 @Provides 注解一个构造方法来提供依赖的过程。
public class Person {
@Inject
Car car;
public void goDongbei(){
car.run();
}
}
@Module
public class PersonModule {
@Provides
public Car provideCar(){
return new Car();
}
}
@Component(modules = PersonModule.class)
public interface PersonComponent {
void inject(Person person);
}
public class Car {
private static final String TAG = "Car";
public void run(){
Log.d(TAG, "run: ~~~~~~");
}
}
此时,build一把工程,然后添加如下代码:
Person person = new Person();
DaggerPersonComponent.builder().build().inject(person);
person.goShopping();
2019-04-17 16:35:08.602 5843-5843/? D/Car: run: 速度180,出发去东北
问题又来了,Dagger 怎么凭借 DaggerPersonComponent.builder().build().inject(person) 一个链式调用就把 Car 对象注入到 Person 的呢?
先看看 DaggerPersonComponent 到底是什么?
DaggerPersonComponent 为工程 build 后 Dagger 利用注解自动生成的代码:
// Generated by dagger.internal.codegen.ComponentProcessor (https://google.github.io/dagger).
package com.example.di.component;
public final class DaggerPersonComponent implements PersonComponent {
private Provider provideCarProvider;
private MembersInjector personMembersInjector;
private DaggerPersonComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static PersonComponent create() {
return builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.provideCarProvider = PersonModule_ProvideCarFactory.create(builder.personModule);
this.personMembersInjector = Person_MembersInjector.create(provideCarProvider);
}
@Override
public void inject(Person person) {
personMembersInjector.injectMembers(person);
}
public static final class Builder {
private PersonModule personModule;
private Builder() {}
public PersonComponent build() {
if (personModule == null) {
this.personModule = new PersonModule();
}
return new DaggerPersonComponent(this);
}
public Builder personModule(PersonModule personModule) {
this.personModule = Preconditions.checkNotNull(personModule);
return this;
}
}
}
在构建DaggerPersonComponent时,显示的传入一个 PersonModule 对象,如下所示:
DaggerPersonComponent.builder().personModule(new PersonModule()).build()
在构建DaggerPersonComponent时,不传 PersonModule 对象,如下所示:
DaggerPersonComponent.builder().build()
此时,Builder还是会自动构建一个 PersonModule 对象:
public PersonComponent build() {
if (personModule == null) {
this.personModule = new PersonModule();
}
return new DaggerPersonComponent(this);
}
PersonModule 类是我们自己定义的,主要用来提供 car 对象。
使用简单工厂模式,创建一个 PersonModule_ProvideCarFactory 对象,该对象会持有 PersonModule 对象的引用,并提供一个 get 方法用来调用 module.provideCar(),源码如下:
public final class PersonModule_ProvideCarFactory implements Factory {
private final PersonModule module;
public PersonModule_ProvideCarFactory(PersonModule module) {
assert module != null;
this.module = module;
}
@Override
public Car get() {
return Preconditions.checkNotNull(
module.provideCar(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory create(PersonModule module) {
return new PersonModule_ProvideCarFactory(module);
}
}
PersonModule_ProvideCarFactory 对象可以看成是PersonModule对象的一个Wrapper。
使用简单工厂模式,创建一个 Person_MembersInjector 对象,该对象会持有 PersonModule_ProvideCarFactory 对象的引用,并提供一个 injectMembers 方法,源码如下:
public final class Person_MembersInjector implements MembersInjector {
private final Provider carProvider;
public Person_MembersInjector(Provider carProvider) {
assert carProvider != null;
this.carProvider = carProvider;
}
public static MembersInjector create(Provider carProvider) {
return new Person_MembersInjector(carProvider);
}
@Override
public void injectMembers(Person instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.car = carProvider.get();
}
public static void injectCar(Person instance, Provider carProvider) {
instance.car = carProvider.get();
}
}
Person_MembersInjector对象主要负责依赖的注入,上面的 injectMembers 方法就是给需要依赖的对象注入 car。
当调用 DaggerPersonComponent.builder().build() 方法后,即会创建一个 DaggerPersonComponent 对象,源码如下:
public PersonComponent build() {
if (personModule == null) {
this.personModule = new PersonModule();
}
return new DaggerPersonComponent(this);
}
其实在创建 DaggerPersonComponent 对象过程中,已经顺带创建了 PersonModule 对象、PersonModule_ProvideCarFactory 以及 Person_MembersInjector 对象。
调用 DaggerPersonComponent 对象的 inject(person) 方法时,Person_MembersInjector 对象会从 PersonModule_ProvideCarFactory 获取 car 对象来注入给 person。