这里根据简单基础的注入来分析一些基础注入的原理。不明白基础的请看上一篇重新认识Dagger2文章
Dagger2是通过apt插件在编译阶段生成相应的注入代码的。在完成上面那个例子Rebuild Project编译成功之后,Dagger2会在/app/build/generated/apt/debug/目录下生成一些对应的工厂类
我们看下面具体代码,我们先看MainPersenter这个类,这个类中的构造函数中用了@Inject标注
@Inject
MainPersenter(MainView.View view) {
mView = view;
}
编译成功之后MainPersenter也在 MainPresenter_Factory生成相对应的代码
public final class MainPersenter_Factory implements Factory<MainPersenter> {
private final Provider<MainView.View> viewProvider;
public MainPersenter_Factory(Provider<MainView.View> viewProvider) {
assert viewProvider != null;
this.viewProvider = viewProvider;
}
@Override
public MainPersenter get() {
return new MainPersenter(viewProvider.get());
}
public static Factory<MainPersenter> create(Provider<MainView.View> viewProvider) {
return new MainPersenter_Factory(viewProvider);
}
}
有个viewProvide是Provider类型,在构造函数实例化,泛型参数是MainView.View,看到Provider应该就知道MainView.View是一个依赖,而这个依赖的提供着就是MainModule了,所以这个viewProvide是由MainModule提供的。看源码可以看到有个get()方法,里面是MainPersenter的实例化,构造函数里面的参数就是MainView.View,由viewProvider.get()提供,然后就是create方法创建MainPersenter_Factory类,由此得出viewProvider是由MainModule提供的,接下来看看MainModule对应的注入类。
@Provides
MainView.View provideMainView() {
return mView;
}
在MainModule中定义的@Provides修饰的方法会对应的生成一个工厂类
public final class MainModule_ProvideMainViewFactory implements Factory<MainView.View> {
private final MainModule module;
public MainModule_ProvideMainViewFactory(MainModule module) {
assert module != null;
this.module = module;
}
@Override
public MainView.View get() {
return Preconditions.checkNotNull(
module.provideMainView(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<MainView.View> create(MainModule module) {
return new MainModule_ProvideMainViewFactory(module);
}
}
跟MainModule是相对应的就是这个MainModule_ProvideMainViewFactory类,下面的get()方法,内部调用的就是MainModule里面的 provideMainView()方法来返回所需要的MainView.View依赖,看回MainPresenter_Factory里的get()方法中,实例化MainPresenter时候的参数是viewProvider.get(),看到这些可以得到,原来那个viewProvider就是生成的MainModule_ProvideMainViewFactory,然后调用了其get()方法,将我们需要的MainContract.View依赖注入到MainPresenter里。这就是MainPresenter的实例化过程了,MainPresenter会对应的有一个工厂类,在这个类的get()方法中进行MainPresenter创建,而MainPresenter所需要的MainView.View依赖,是由MainModule里定义的以@Provide开头的方法所对应的工厂类提供的。这是实例化的过程,那create方法又是怎么跟@Inject标注MainPersenter关联起来,前面说过Component是连接@Module和@Inject的桥梁,那就是Component了,下面看看代码:
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainActivity activity);
}
public final class DaggerMainComponent implements MainComponent {
private Provider<MainView.View> provideMainViewProvider;
private Provider<MainPersenter> mainPersenterProvider;
private MembersInjector<MainActivity> mainActivityMembersInjector;
private DaggerMainComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.provideMainViewProvider = MainModule_ProvideMainViewFactory.create(builder.mainModule);
this.mainPersenterProvider = MainPersenter_Factory.create(provideMainViewProvider);
this.mainActivityMembersInjector = MainActivity_MembersInjector.create(mainPersenterProvider);
}
@Override
public void inject(MainActivity activity) {
mainActivityMembersInjector.injectMembers(activity);
}
public static final class Builder {
private MainModule mainModule;
private Builder() {}
public MainComponent build() {
if (mainModule == null) {
throw new IllegalStateException(MainModule.class.getCanonicalName() + " must be set");
}
return new DaggerMainComponent(this);
}
public Builder mainModule(MainModule mainModule) {
this.mainModule = Preconditions.checkNotNull(mainModule);
return this;
}
}
}
从上面的代码可以看到,我们之前定义的MainComponent方法会生成一个对应的DaggerMainComponent类,并且实现了MainComponent类,在生成的代码中也有Provider所提供的依赖,它们靠MainComponent关联起来,是靠initialize方法实例化的,创建了MainModule_ProvideMainViewFactory用来提供MainView.View依赖,然后将provideMainViewProvider传递给MainPersenter_Factory,就是前面说的viewProvider,接着将这个mainPresenterProvider又传递到MainActivity_MembersInjector中进行实例化,我们可以想到这就是MainActivity相对应的注入类。
这里我们先看看create()方法,返回的是Factory类型,而provideMainViewProvider是个Provider类型,其实看源码就明白了,Factory仅仅继承一个Provider,并是一个空的实现。
public interfaceFactory<T> extends Provider<T> {}
接着是我们在MainComponent里定义的Inject方法的实现,这里调用了mainActivityMembersInjector.injectMembers(activity)方法,将我们的MainActivity注入到该类中。看看injectMembers方法
/**
* Injects dependencies into the fields and methods on instances of type {@code T}. Ignores the
* presence or absence of an injectable constructor.
*
* @param <T> type to inject members of
*
* @author Bob Lee
* @author Jesse Wilson
* @since 2.0 (since 1.0 without the provision that {@link #injectMembers} cannot accept
* {@code null})
*/
public interface MembersInjector<T> {
/**
* Injects dependencies into the fields and methods of {@code instance}. Ignores the presence or
* absence of an injectable constructor.
*
* <p>Whenever the object graph creates an instance, it performs this injection automatically
* (after first performing constructor injection), so if you're able to let the object graph
* create all your objects for you, you'll never need to use this method.
*
* @param instance into which members are to be injected
* @throws NullPointerException if {@code instance} is {@code null}
*/
void injectMembers(T instance);
}
从类的注释中,可以看出它的主要作用是给类的属性字段,或者方法参数来提供注入,并忽略是否在含有构造器的注入,都会生成MembersInjector的类。
接着就是Builder内部类,用来创建我们的module以及自身实例。在build() 方法里面主要用来初始化DaggerMainComponent再去初始化依赖,而真正的将这些依赖于Inject关联起来的就是MainActivity_MembersInjector类,看看这个类里做了什么。
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
private final Provider<MainPersenter> mainPresenterProvider;
public MainActivity_MembersInjector(Provider<MainPersenter> mainPresenterProvider) {
assert mainPresenterProvider != null;
this.mainPresenterProvider = mainPresenterProvider;
}
public static MembersInjector<MainActivity> create(
Provider<MainPersenter> mainPresenterProvider) {
return new MainActivity_MembersInjector(mainPresenterProvider);
}
@Override
public void injectMembers(MainActivity instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.mainPresenter = mainPresenterProvider.get();
}
public static void injectMainPresenter(
MainActivity instance, Provider<MainPersenter> mainPresenterProvider) {
instance.mainPresenter = mainPresenterProvider.get();
}
}
这个类的最重要的就是injectMembers()方法,就在刚才提到的DaggerMainComponent类中的inject()方法里也调用了,所以这里的instance实例是由DaggerMainComponent提供的,然后我们看到下面一句关键的代码
instance.mainPresenter= mainPresenterProvider.get();
从上方可以看出,MainActivity_MembersInjector类通过实现MembersInjector类,通过injectMembers方法将mainPresenterProvider中创建好的MainPresenter实例赋值给instance(MainActivity)的成员mainPresenter,采用Provider获取实例的方式,来给我们之前定义的Inject参数或者属性,来赋值相应的注入类。接着就可以在代码中使用了。到这里,就分析完了Dagger2的注入过程