Dagger2源碼分析-最簡單的注入過程

rrmr1339 9年前發布 | 11K 次閱讀 Dagger 源碼分析 Android開發 移動開發

Dagger要實現的類以及APT生成的類

Dagger2最簡單的依賴注入實踐

要實現三個類:

  1. Dagger2Activity
  2. ActivityComponent
  3. ActivityModule

直接上代碼:

1、Dagger2Activity

public class Dagger2Activity extends Activity {

    private ActivityComponent mActivityComponent;

    @Inject
    UserModel mUserModel;

    @Bind(R.id.tv_user_id)
    TextView tvUserId;
    @Bind(R.id.tv_user_name)
    TextView tvUserName;
    @Bind(R.id.tv_user_gender)
    TextView tvUserGender;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ex_dagger2_activity);
        ButterKnife.bind(this);

        mActivityComponent = DaggerActivityComponent.builder().activityModule(new ActivityModule(1, "Leon", 1)).build();
        mActivityComponent.inject(this);

        tvUserId.setText(mUserModel.id + "");
        tvUserName.setText(mUserModel.name);
        tvUserGender.setText(mUserModel.gender + "");
    }
}

2、ActivityComponent

@Component(modules = ActivityModule.class)
public interface ActivityComponent {

    void inject(Dagger2Activity activity);
}

3、ActivityModule

@Module
public class ActivityModule {

    private UserModel mUserModel;

    public ActivityModule(long userId, String userName, int gender) {
        mUserModel = new UserModel(userId, userName, gender);
    }

    @Provides
    UserModel provideUserModel() {
        return mUserModel;
    }
}

列出所有類

使用Dagger,要實現

Dagger2Activity 、 ActivityComponent 、 ActivityModule

三個類,Make Project之后生成三個類:

  • DaggerActivityComponent
  • Dagger2Activity_MemberInject
  • ActivityModule_ProviderUserModelFactory

分析代碼

注入程序的入口

mActivityComponent.inject(this);
@Component(modules = ActivityModule.class)
public interface ActivityComponent {

    void inject(ExDagger2Activity activity);
}

直接調用的是ActivityComponent的inject。ActivityComponent是個接口,實現類是DaggerActivityComponent。

@Override
  public void inject(ExDagger2Activity activity) {
    exDagger2ActivityMembersInjector.injectMembers(activity);
  }

注意,inject接收被注入的實例參數。接下來的 DaggerActivityComponent的注入工作 應該是:

  • 找到被注入的Activity中被@Inject注解的成員mUserModel變量;
  • 然后賦值給mUserModel

DaggerActivityComponent有兩個成員變量:

private Provider<UserModel> provideUserModelProvider;//負責提供對象
private MembersInjector<ExDagger2Activity> dagger2ActivityMembersInjector;//負責給被@Inject的成員變量賦值

賦值給被@Inject的成員變量

DaggerActivityComponent的inject調用的是dagger2ActivityMembersInjector的injectMembers,實現如下:

Dagger2Activity_MembersInjector.java

@Override
  public void injectMembers(ExDagger2Activity instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.mUserModel = mUserModelProvider.get();
  }

從mUserModelProvider中獲取對象賦值給被注入類Dagger2Activity的mUserModel成員變量(所以,mUserModel必須是public的)。

mUserModelProvider從哪里來的?

DaggerActivityComponent.java

private void initialize(final Builder builder) {

    this.provideUserModelProvider =
        ActivityModule_ProvideUserModelFactory.create(builder.activityModule);

    this.exDagger2ActivityMembersInjector =
        ExDagger2Activity_MembersInjector.create(provideUserModelProvider);
  }

DaggerActivityComponent初始化他的兩個成員變量時,傳入的。也就是說,賦值提供對象的是provideUserModelProvider(看名字也知道了)。

輪到ActivityModule發揮作用了:創建對象

ActivityModule生成了一個工廠類ActivityModule_ProvideUserModelFactory。這個工廠類是專門生產UserModel對象的。

@Module
public class ActivityModule {

    private UserModel mUserModel;

    public ActivityModule(long userId, String userName, int gender) {
        mUserModel = new UserModel(userId, userName, gender);
    }

    @Provides
    UserModel provideUserModel() {
        return mUserModel;
    }
}

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class ActivityModule_ProvideUserModelFactory implements Factory<UserModel> {
  private final ActivityModule module;

  public ActivityModule_ProvideUserModelFactory(ActivityModule module) {
    assert module != null;
    this.module = module;
  }

  @Override
  public UserModel get() {
    return Preconditions.checkNotNull(
        module.provideUserModel(), "Cannot return null from a non-@Nullable @Provides method");
  }

  public static Factory<UserModel> create(ActivityModule module) {
    return new ActivityModule_ProvideUserModelFactory(module);
  }
}

放在一起對比。ActivityModule的provideUserModel方法創建了對象,被ActivityModule_ProvideUserModelFactory的get方法獲取。

總結

分析完代碼之后,再看看文章開頭的類圖。Make Project之后生產三個類的作用分別是:

  • DaggerActivityComponent:程序入口,負責串聯創建對象與賦值。
  • Dagger2Activity_MemberInject:持有被注入的對象DaggerActivity,賦值給被@Inject的成員變量。
  • ActivityModule_ProviderUserModelFactory:創建對象。

 

來自:http://www.jianshu.com/p/14841af5b462

 

 本文由用戶 rrmr1339 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!