Dagger2源码浅析

Posted sharkchao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dagger2源码浅析相关的知识,希望对你有一定的参考价值。

dagger2是目前android端比较火的一款依赖注入框架,先来看下基本的用法吧:

首先提供module,类似于工厂:

@Module
public class ApiServiceModule {
    private static final String ENDPOINT = "";
    @Singleton
    @Provides
    public OkHttpClient providerOkHttpClient(){
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.setConnectTimeout(60 * 1000, TimeUnit.MILLISECONDS);
        okHttpClient.setReadTimeout(60 * 1000, TimeUnit.MILLISECONDS);
        return okHttpClient;
    }
    @Singleton
    @Provides
    public RestAdapter providerRestAdapter(OkHttpClient okHttpClient){
        RestAdapter.Builder builder = new RestAdapter.Builder();
        builder.setClient(new OkClient(okHttpClient))
                .setEndpoint(ENDPOINT);
        return builder.build();
    }
    @Singleton
    @Provides
    public ApiService providerApiService(RestAdapter adapter){
        return adapter.create(ApiService.class);
    }
}

 

然后是component组件,用来连接module与需求方:

@Singleton
@Component(modules = {AppModule.class , ApiServiceModule.class , AppServiceModule.class})
public interface AppComponent {
    Application getApplication();
    ApiService getService();
    User getUser();
}

在activity中使用:

public class MainActivity extends BaseActivity {

    private TextView tvName;
    @Inject
    MainPresenter mMainPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvName = findViewById(R.id.tvName);
        mMainPresenter.showUserName();
    }

    @Override
    protected void setupActivityComponent(AppComponent appComponent) {
        DaggerMainActivityComponent.builder()
                .appComponent(appComponent)
                .mainActivityModule(new MainActivityModule(this))
                .build().inject(this);
    }

    public void setTextName(String name){
        tvName.setText(name);
    }
}

使用是非常简单的,下面来看一下dagger2是如何做到依赖注入的吧:

首先会调到    DaggerMainActivityComponent.builder() ,我们会想到构建者模式,一起看下源码

  public static Builder builder() {
    return new Builder();
  }

Builder的构造函数中没有做任何处理,接下来看下.build方法:

 public MainActivityComponent build() {
      if (mainActivityModule == null) {
        throw new IllegalStateException(
            MainActivityModule.class.getCanonicalName() + " must be set");
      }
      if (appComponent == null) {
        throw new IllegalStateException(AppComponent.class.getCanonicalName() + " must be set");
      }
      return new DaggerMainActivityComponent(this);
    }
 new DaggerMainActivityComponent(this) 会初始化component,然后将builder传递进去,这也是建造者模式的一般写法,下面看下其中的构造函数会执行哪些方法呢
  private void initialize(final Builder builder) {
    this.providerMainActivityProvider =
        DoubleCheck.provider(
            MainActivityModule_ProviderMainActivityFactory.create(builder.mainActivityModule));
    this.getUserProvider =
        new com_winning_mvp_dagger2_retrofit_master_di_component_AppComponent_getUser(
            builder.appComponent);
    this.providerMainPresenterProvider =
        DoubleCheck.provider(
            MainActivityModule_ProviderMainPresenterFactory.create(
                builder.mainActivityModule, providerMainActivityProvider, getUserProvider));
  }

下面我们来单独看一下这句

this.providerMainActivityProvider =
    DoubleCheck.provider(
        MainActivityModule_ProviderMainActivityFactory.create(builder.mainActivityModule));

走到MainActivityModule_ProviderMainActivityFactory中看一下:
 
public final class MainActivityModule_ProviderMainActivityFactory implements Factory<MainActivity> {
  private final MainActivityModule module;

  public MainActivityModule_ProviderMainActivityFactory(MainActivityModule module) {
    this.module = module;
  }

  @Override
  public MainActivity get() {
    return provideInstance(module);
  }

  public static MainActivity provideInstance(MainActivityModule module) {
    return proxyProviderMainActivity(module);
  }

  public static MainActivityModule_ProviderMainActivityFactory create(MainActivityModule module) {
    return new MainActivityModule_ProviderMainActivityFactory(module);
  }

  public static MainActivity proxyProviderMainActivity(MainActivityModule instance) {
    return Preconditions.checkNotNull(
        instance.providerMainActivity(),
        "Cannot return null from a [email protected] @Provides method");
  }
}

 

现在component中的属性都是有值的了,最后看下inject做了哪些操作:
  public static void injectMMainPresenter(MainActivity instance, MainPresenter mMainPresenter) {
    instance.mMainPresenter = mMainPresenter;
  }

到这里依赖注入就已经完成了,这里只是分析了最简单的注入方式。

 

技术分享图片

 



以上是关于Dagger2源码浅析的主要内容,如果未能解决你的问题,请参考以下文章

Android Dragger2快速入门浅析

Android 常用开源框架源码解析 系列 dagger2 呆哥兔 依赖注入库

Dagger2下的ViewModel

Java框架!Dagger2源码分析(三

Dagger2教程六之Component的组织方法(原)

Android -- 带你从源码角度领悟Dagger2入门到放弃