Dagger2依赖注入


Dagger2,一个依赖注入框架,在编译时处理注解,自动生成.java文件,Mvp架构中使用Dagger2,不需要手动创建Presenter,通过注解注入宿主Activity。

代码结构

LoginComponent接口,用@Component和@ActivityScope注解,提供注入方法和注入目的类。

@ActivityScope
@Component(modules = LoginModule.class)
public interface LoginComponent {
    void inject(LoginActivity activity);
}

LoginModule类,@Module注解,provider方法,用@Provides和@ActivityScope注解,提供注入对象构造参数。

@Module
public class LoginModule {
    private ILoginView iView;
    public LoginModule(ILoginView iView) {
        this.iView = iView;
    }
    @Provides
    @ActivityScope
    public ILoginView provideILoginView() {
        return this.iView;
    }
}

LoginPresenter,注入对象,构造方法@Inject注解。

@Inject
public LoginPresenter(ILoginView iView, long id, String userName) {
    this.iLoginView = iView;
    this.id = id;
    this.userName = userName;
}

在Activity内部,定义LoginPresenter,@Inject注解。

@Inject
LoginPresenter mLoginPresenter;

DaggerLoginComponent.builder().loginModule(new LoginModule(this)).build().inject(this);

Activity不需要主动创建LoginPresenter对象,调用inject注入方法,直接使用。
DaggerLoginComponent是一个自动生成的java类,实现LoginComponent接口,该接口自定义。
DaggerLoginComponent包含Provider引用,注入对象构造参数的Provider提供者。

private Provider provideILoginViewProvider;
private Provider getIdProvider;
private Provider getUserNameProvider;

DaggerLoginComponent内部类Builder,封装Module,loginModule方法,设置LoginModule对象,LoginModule类是注入对象构造参数具体提供者。
build方法,创建DaggerLoginComponent对象,构造方法入参Builder对象。

private DaggerLoginComponent(Builder builder) {
    initialize(builder);
}

根据Builder的LoginModule类,初始化DaggerLoginComponent内部的Provider,即参数工厂,每一个构造参数,都生成一个构造工厂类。

private void initialize(final Builder builder) {
    this.provideILoginViewProvider =
        DoubleCheck.provider(LoginModule_ProvideILoginViewFactory.create(builder.loginModule));
    this.getIdProvider = DoubleCheck.provider(LoginModule_GetIdFactory.create(builder.loginModule));
    this.getUserNameProvider =
        DoubleCheck.provider(LoginModule_GetUserNameFactory.create(builder.loginModule));
}

LoginModule_ProvideILoginViewFactory类,实现Factory,Factory继承Provider,根据Builder对象内部配置的LoginModel,工厂提供静态create方法创建工厂对象,工厂封装LoginModule。
每个工厂实现Provider接口get方法,具体由内部LoginModule类提供参数。
inject方法,传入被注入的对象LoginActivity。

@Override
public void inject(LoginActivity activity) {
    injectLoginActivity(activity);
}

调用内部injectLoginActivity方法。

private LoginActivity injectLoginActivity(LoginActivity instance) {
    LoginActivity_MembersInjector.injectMLoginPresenter(instance, getLoginPresenter());
    return instance;
}

injectMLoginPresenter方法,将LoginPresenter对象其赋值给LoginActivity实例对象内部变量。
getLoginPresenter方法,返回LoginPresenter注入对象,构造方法@Inject注解。

private LoginPresenter getLoginPresenter() {
    return new LoginPresenter(
        provideILoginViewProvider.get(), getIdProvider.get(), getUserNameProvider.get());
}

LoginPresenter构造方法参数,参数工厂Provider提供,get方法,调用内部LoginModule的@Provides注解方法。

Dagger2的本质是通过Apt技术自动生成对象并赋值注入。

Dagger2自动生成类的结构图

Dagger2解耦Activity和Presenter,当改动LoginPresenter的构造方法时,不需要改动Activity。比如我在LoginPresenter的构造方法增加一个参数userName,这时,只需要在LoginModule类中,添加一个@Provides注解的方法,该方法返回一个String类型userName即可。


任重而道远

你可能感兴趣的:(Dagger2依赖注入)