Dagger2 生成代码学习笔记

上一篇记录了如何使用Dagger,其中还漏了一些内容,回头再补。今天来看看Dagger在预编译时期生成的辅助代码,看看Dagger做依赖注入的实现原理是咋样的。
还是从上一篇中最简单的Sample开始。先看下代码:
MainActivity:

public class MainActivity extends AppCompatActivity {

    @Inject
    UserModel user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

        ((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + "::Age:" + user.getAge());
    }
}

UserModel:

public class UserModel {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

UserModule:

@Module
public class UserModule {

    UserModule() {}

    @Provides
    UserModel provideUsers() {
        UserModel user = new UserModel();
        user.setName("lala");
        user.setAge(18);
        return user;
    }
}

UserComponent:

@Component(modules = {UserModule.class})
public interface UserComponent {
    void inject(MainActivity mainActivity);
}

运行结果如下:


Dagger2 生成代码学习笔记_第1张图片
Screenshot_2017-02-08-11-40-46.png

OK,咱们先来看看Dagger为我们上面的代码生成了哪些东东。
咱们自己的类:
1.MainActivity
2.UserComponent
3.UserModel
4.UserModule
Dagger生成的类:
1.DaggerUserComponent
2.UserModule_ProvideUsersFactory
3.MainActivity_MembersInjector
好,下面来逐个看看这几个生成类

直接从我们执行注入的代码下手:

DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

可以看到,我们通过Builder方式,传一个UserModule的实例,build一个DaggerUserComponent的实例出来,然后调用 inject 方法执行注入操作。
下面喽一眼DaggerUserComponent的代码。
DaggerUserComponent:

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerUserComponent implements UserComponent {
  private Provider provideUsersProvider;
  private MembersInjector mainActivityMembersInjector;

  private DaggerUserComponent(Builder builder) {  
    assert builder != null;
    initialize(builder);
  }

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

  public static UserComponent create() {  
    return builder().build();
  }

  private void initialize(final Builder builder) {  
    this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

  @Override
  public void inject(MainActivity mainActivity) {  
    mainActivityMembersInjector.injectMembers(mainActivity);
  }

  public static final class Builder {
    private UserModule userModule;
  
    private Builder() {  
    }
  
    public UserComponent build() {  
      if (userModule == null) {
        this.userModule = new UserModule();
      }
      return new DaggerUserComponent(this);
    }
  
    public Builder userModule(UserModule userModule) {  
      if (userModule == null) {
        throw new NullPointerException("userModule");
      }
      this.userModule = userModule;
      return this;
    }
  }
}

这个类非常简单,它实现了咱们写的UserComponent接口,实现了inject方法。重点在初始化 (initialize) 和注入 (inject) 两个方法。

private Provider provideUsersProvider;
private MembersInjector mainActivityMembersInjector;

private void initialize(final Builder builder) {  
    this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

可以看到,initialize这个方法创建了两个成员变量,provideUsersProvidermainActivityMembersInjector
创建Provider的代码引出了第二个生成类: UserModule_ProvideUserFactory

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class UserModule_ProvideUsersFactory implements Factory {
  private final UserModule module;

  public UserModule_ProvideUsersFactory(UserModule module) {  
    assert module != null;
    this.module = module;
  }

  @Override
  public UserModel get() {  
    UserModel provided = module.provideUsers();
    if (provided == null) {
      throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
    }
    return provided;
  }

  public static Factory create(UserModule module) {  
    return new UserModule_ProvideUsersFactory(module);
  }
}

顾名思义,UserModule_ProvideUsersFactory 是一个工厂类,此类用来生产我们用 @Inject 注解的UserModel实例。
上面这句是屁话,UserModel的真正的实例并不在这里生产,可以看到,这个“伪工厂”接受一个咱们写的UserModule的实例,然后在get方法中调用UserModule的provideUsers()方法(咱们自己写的),把拿到的UserModel实例返回。
咱们回到DaggerUserComponent,再瞄一眼初始化的第一句代码:
this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
在这里创建了一个生产UserModel实例的工厂实例。该实例的get方法返回一个UserModel的实例(从Module的provide方法中拿到的)。
OK,拿到了Provider的实例,来看看初始化的第二行代码:
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
这里引出了第三个生成类,MainActivity_MembersInjector.

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MainActivity_MembersInjector implements MembersInjector {
  private final MembersInjector supertypeInjector;
  private final Provider userProvider;

  public MainActivity_MembersInjector(MembersInjector supertypeInjector, Provider userProvider) {  
    assert supertypeInjector != null;
    this.supertypeInjector = supertypeInjector;
    assert userProvider != null;
    this.userProvider = userProvider;
  }

  @Override
  public void injectMembers(MainActivity instance) {  
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    supertypeInjector.injectMembers(instance);
    instance.user = userProvider.get();
  }

  public static MembersInjector create(MembersInjector supertypeInjector, Provider userProvider) {  
      return new MainActivity_MembersInjector(supertypeInjector, userProvider);
  }
}

MainActivity_MembersInjector的create方法接收两个参数,生成一个实例返回。这个类实现了MembersInjector接口,实现了injectMembers方法,咦?
instance.user = userProvider.get();
真相只有一个,这一句才是真正执行注入的代码。从接收到的Provider实例中通过调用get方法拿到UserModel实例,并赋给传进来的MainActivity实例的user成员变量。这也是为什么我们用 @Inject 注解的变量不可以是private的原因。
所以这么看下来,注入过程还是很简单的,像很多文章说的那样,There is no magic with Dagger.
就在飘飘然的时候,瞄见了这句代码
supertypeInjector.injectMembers(instance);
supertypeInjector?这个是初始化的时候创建塞进来的:

this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);

注意这里有两个长得很像的类,MembersInjector 和 MembersInjectors,卧槽。
MembersInjector是一个接口,就是上面提到的那个,里面只有一个injectMembers抽象方法。那MembersInjectors是什么鬼...

public final class MembersInjectors {
  /**
   * Returns a {@link MembersInjector} implementation that injects no members
   *
   * 

Note that there is no verification that the type being injected does not have {@link Inject} * members, so care should be taken to ensure appropriate use. */ @SuppressWarnings("unchecked") public static MembersInjector noOp() { return (MembersInjector) NoOpMembersInjector.INSTANCE; } private static enum NoOpMembersInjector implements MembersInjector { INSTANCE; @Override public void injectMembers(Object instance) { if (instance == null) { throw new NullPointerException(); } } } /** * Returns a {@link MembersInjector} that delegates to the {@link MembersInjector} of its * supertype. This is useful for cases where a type is known not to have its own {@link Inject} * members, but must still inject members on its supertype(s). * *

Note that there is no verification that the type being injected does not have {@link Inject} * members, so care should be taken to ensure appropriate use. */ @SuppressWarnings("unchecked") public static MembersInjector delegatingTo(MembersInjector delegate) { return (MembersInjector) delegate; } private MembersInjectors() {} }

初始化中调用的noOp方法返回一个NoOpMembersInjector枚举类,这个类同样实现了MembersInjector接口,在injectMembers方法中check了instance是否为null。
什么鬼,在注入前不是已经check过了么:

@Override
  public void injectMembers(MainActivity instance) {  
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    supertypeInjector.injectMembers(instance);
    instance.user = userProvider.get();
  }

这个鬼地方先按下不表,因为我也布吉岛,回头再看看回来补上,现在看不懂为什么要连着check两次。

除了上面这个问题,对于Dagger依赖注入的流程应该是比较清晰的。首先build一个DaggerUserComponent实例,把Module传进去,再调它的inject方法,DaggerUserComponent的inject方法会调到MainActivityMembersInjector的injectMembers方法,在这里执行真正的注入。

以上是依赖注入一个实例时Dagger生成的辅助代码。如果我们给两个成员注入,如下:

public class MainActivity extends AppCompatActivity {

    @Inject
    UserModel user1;

    @Inject
    UserModel user2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

        user2.setName("Arya Stark");
        user2.setAge(12);

        ((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
        ((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());
    }
}

就不传图了,结果是两个不一样的TextView内容,因为这是两个不同的实例。
那么问题来了,那单例呢?
还是用这个Sample,我给Component类和provide方法都加上 @Singleton 注解,最后的得到的结果就是单例,怎么做到的?
对比了代码后,我发现加Singleton注解和不加两种情况下,DaggerUserComponent的初始化代码偷偷发生了变化。
不加 @Singleton 注解:

private void initialize(final Builder builder) {  
    this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

加 @Singleton注解:

private void initialize(final Builder builder) {  
    this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(builder.userModule));
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

看出区别了吧?不加注解的时候拿到的Provider是UserModule_ProvideUsersFactory的实例,加了注解后拿到的是ScopedProvider的实例。
好,来看看这个ScopedProvider.

/**
 * A {@link Provider} implementation that memoizes the result of a {@link Factory} instance.
 *
 * @author Gregory Kick
 * @since 2.0
 */
public final class ScopedProvider implements Provider {
  private static final Object UNINITIALIZED = new Object();

  private final Factory factory;
  private volatile Object instance = UNINITIALIZED;

  private ScopedProvider(Factory factory) {
    assert factory != null;
    this.factory = factory;
  }

  @SuppressWarnings("unchecked") // cast only happens when result comes from the factory
  @Override
  public T get() {
    // double-check idiom from EJ2: Item 71
    Object result = instance;
    if (result == UNINITIALIZED) {
      synchronized (this) {
        result = instance;
        if (result == UNINITIALIZED) {
          instance = result = factory.get();
        }
      }
    }
    return (T) result;
  }

  /** Returns a new scoped provider for the given factory. */
  public static  Provider create(Factory factory) {
    if (factory == null) {
      throw new NullPointerException();
    }
    return new ScopedProvider(factory);
  }
}

其实所谓的ScopedProvider就是把Factory包了一层,在里面存储了Factory的实例。当我们调用inject时,DaggerUserComponent会把调用转发给Provider,此时也就是ScopedProvider的get方法,单例的关键就在这里。
这个类里定义了一个静态常量UNINITIALIZED,第一次进入get方法时,会把现在还是静态常量的instance赋给result局部变量。然后进入判断,拿锁,从factory实例中取出UserModel实例,赋给instance和result,然后把result返回。此时,instance变量已经变成了我们之前拿到的那个UserModel实例了。后面再进来,局部变量result(之前的UserModel实例)和静态常量不等,就再也进不去判断,直接返回instance,也就实现了单例。
但是注意,这个单例是存在于DaggerUserComponent的实例中的,也就是说,如果DaggerUserComponent产生了新的实例,那么也会产生新的UserModel实例。不能光说不练,来做个实验。
对MainActivity做以下更改:

public class MainActivity extends AppCompatActivity {

    @Inject
    UserModel user1;

    @Inject
    UserModel user2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

        user2.setName("Arya Stark");
        user2.setAge(12);

        ((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
        ((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                DaggerUserComponent.builder()
                        .userModule(new UserModule())
                        .build()
                        .inject(MainActivity.this);
                ((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
                ((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());
            }
        }, 2000);
    }
}

在第一次设置TextView的文字完了两秒后,重新进行一次注入,再更新TextView的显示。现象就是,先显示Arya Stark的信息,两秒后更新为十八岁的lala。因为第二次注入时生成了DaggerUserComponent的新实例,单例也就失效了。

自定义 @UserScope 注解
既然前面已经把Dagger中的 @Singleton 的实现扒了个精光,那么应该很容易自定义Scope了。因为单例存在于ScopedProvider,而ScopedProvider是在Component中创建的,所以要自定义Scope,其实就是控制好Dagger给咱们生成的Component实现的生命周期。
哦对了,先想想Scope是干啥的。我的理解是,保证某个类在一个时期中的实例的单一,也就是在定义的时期中是单例。比如我希望我们的CP项目Model在项目Activity中是单例,那么就可以定义一个ActivityScope,我希望我们的UserModel在用户登陆后直到登出前是一个单例,那么就定义一个从登陆到登出的UserScope。
现在拓展一下我们的Sample. 在MainActivity之外,再创建SecondActivity和ThirdActivity,假设咱们的用户在SecondActivity登录,我们需要UserModel在SecondActivity到ThirdActivity之间是单例。
OK,既然UserScope跨Activity,那只能在比Activity更大的Scope下定义了,这个Scope只能是整个App的ApplicationScope。
好吧,咱们还是按流程来。先为整个App定义最大的Component:

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

    UserComponent plus(UserModule userModule);

}

注解里标识的AppModule:

@Module
public class AppModule {

    private Application application;

    public AppModule(Application application) {
        this.application = application;
    }

    @Provides
    public Application provideApplication() {
        return application;
    }

}

然后添加两个Activity,SecondActivity和ThirdActivity,并为他们分别添加Component和Module,代码就不贴了。
这里咱们要用到一个叫做@Subcomponent的注解,它标识子Component在父Component下进行实现,后面看了源码就明白了,先记着。

@Subcomponent(modules = {SecondActivityModule.class})
public interface SecondActivityComponent {
    SecondActivity inject(SecondActivity secondActivity);
}
@Subcomponent(modules = {ThirdActivityModule.class})
public interface ThirdActivityComponent {
    ThirdActivity inject(ThirdActivity thirdActivity);
}

这两个子Component的接口在inject方法中接收一个自己的Activity,然后返回去。
之后,添加一个Application的子类:

public class DaggerDemoApplication extends Application {

    private AppComponent appComponent;
    private UserComponent userComponent;

    public static DaggerDemoApplication get(Context context) {
        return (DaggerDemoApplication) context.getApplicationContext();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        initAppComponent();
    }

    private void initAppComponent() {
        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }

    public UserComponent createUserComponent() {
        userComponent = appComponent.plus(new UserModule());
        return userComponent;
    }

    public void destroyUserComponent() {
        userComponent = null;
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }

    public UserComponent getUserComponent() {
        return userComponent;
    }
}

注意,要在Manifest里头为Application标签加上name属性,name设为这个类名。这样,这个类就会在整个App启动的时候率先执行。
就像前面说的,因为UserScope跨Activity,所以要把它存在AppScope里头,也就是说当UserScope开始时创建UserComponent的实现并存起来,当UserScope结束的时候,把UserComponent的实例释放。所以在这里有create和destroy两个方法,用于控制UserComponent的生命周期。
创建UserScope注解:

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface UserScope {
}

现在更改一下Activity的内容,把MainActivity的内容更换成一个按钮,用于开启SecondActivity,在SecondActivity上添加两个TextView和一个按钮用于开启ThirdActivity,ThirdActivity只有两个TextView。
MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this, SecondActivity.class));
            }
        });
    }
}
public class SecondActivity extends AppCompatActivity {

    @Inject
    UserModel user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        DaggerDemoApplication.get(this).createUserComponent();

        DaggerDemoApplication.get(this)
                .getUserComponent()
                .plus(new SecondActivityModule())
                .inject(this);

        user.setName("Arya");
        user.setAge(12);
        ((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + ":::Age:" + user.getAge());

        findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(SecondActivity.this, ThirdActivity.class));
            }
        });
    }

    @Override
    public void finish() {
        DaggerDemoApplication.get(this).destroyUserComponent();
        super.finish();
    }
}
public class ThirdActivity extends AppCompatActivity {

    @Inject
    UserModel user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);

        DaggerDemoApplication.get(this)
                .getUserComponent()
                .plus(new ThirdActivityModule())
                .inject(this);

        ((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + ":::Age:" + user.getAge());
    }
}

运行一下。


Dagger2 生成代码学习笔记_第2张图片
Screenshot_2017-02-09-09-48-06.png

Dagger2 生成代码学习笔记_第3张图片
Screenshot_2017-02-09-09-48-10.png

Dagger2 生成代码学习笔记_第4张图片
Screenshot_2017-02-09-09-48-14.png

可以看到,我在SecondActivity和ThirdActivity分别进行了一次注入,只在SecondActivity更改了user的值,结果在ThirdActivity中也生效了,说明这个UserModel实例在SecondActivity和ThirdActivity之间是单例的存在。
下面咱来看看Dagger为咱们生成的代码是怎么做到的。

与之前不同,Dagger在这里并没有生成UserComponent实现的单独类,而是将它作为DaggerAppComponent的内部类。

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerAppComponent implements AppComponent {
  private DaggerAppComponent(Builder builder) {  
    assert builder != null;
  }

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

  @Override
  public UserComponent plus(UserModule userModule) {  
    return new UserComponentImpl(userModule);
  }

  public static final class Builder {
    private AppModule appModule;
  
    private Builder() {  
    }
  
    public AppComponent build() {  
      if (appModule == null) {
        throw new IllegalStateException("appModule must be set");
      }
      return new DaggerAppComponent(this);
    }
  
    public Builder appModule(AppModule appModule) {  
      if (appModule == null) {
        throw new NullPointerException("appModule");
      }
      this.appModule = appModule;
      return this;
    }
  }

  private final class UserComponentImpl implements UserComponent {
    private final UserModule userModule;
    private Provider provideUsersProvider;
  
    private UserComponentImpl(UserModule userModule) {  
      if (userModule == null) {
        throw new NullPointerException();
      }
      this.userModule = userModule;
      initialize();
    }
  
    private void initialize() {  
      this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(userModule));
    }
  
    @Override
    public SecondActivityComponent plus(SecondActivityModule secondActivityModule) {  
      return new SecondActivityComponentImpl(secondActivityModule);
    }
  
    @Override
    public ThirdActivityComponent plus(ThirdActivityModule thirdActivityModule) {  
      return new ThirdActivityComponentImpl(thirdActivityModule);
    }
  
    private final class SecondActivityComponentImpl implements SecondActivityComponent {
      private final SecondActivityModule secondActivityModule;
      private MembersInjector secondActivityMembersInjector;
    
      private SecondActivityComponentImpl(SecondActivityModule secondActivityModule) {  
        if (secondActivityModule == null) {
          throw new NullPointerException();
        }
        this.secondActivityModule = secondActivityModule;
        initialize();
      }
    
      private void initialize() {  
        this.secondActivityMembersInjector = SecondActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
      }
    
      @Override
      public SecondActivity inject(SecondActivity secondActivity) {  
        secondActivityMembersInjector.injectMembers(secondActivity);
        return secondActivity;
      }
    }
  
    private final class ThirdActivityComponentImpl implements ThirdActivityComponent {
      private final ThirdActivityModule thirdActivityModule;
      private MembersInjector thirdActivityMembersInjector;
    
      private ThirdActivityComponentImpl(ThirdActivityModule thirdActivityModule) {  
        if (thirdActivityModule == null) {
          throw new NullPointerException();
        }
        this.thirdActivityModule = thirdActivityModule;
        initialize();
      }
    
      private void initialize() {  
        this.thirdActivityMembersInjector = ThirdActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
      }
    
      @Override
      public ThirdActivity inject(ThirdActivity thirdActivity) {  
        thirdActivityMembersInjector.injectMembers(thirdActivity);
        return thirdActivity;
      }
    }
  }
}

这个类相对比较长,但是也不难理解。可以看一眼我们是如何在DaggerDemoApplication中创建AppComponent和UserComponent的实现的。

private void initAppComponent() {
        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }

    public UserComponent createUserComponent() {
        userComponent = appComponent.plus(new UserModule());
        return userComponent;
    }

父Component AppComponent实现的创建与之前无异,使用它的Builder,传一个AppModule实例再build。而作为子Component的UserComponent的创建就不同了。这里调用AppComponent的plus方法,这个方法是我们定义的接口,接收一个UserModule实例,返回UserComponent.
在我们调用plus的时候,创建了UserComponentImpl实例并返回。在这个内部类中也有两个我们定义的接口方法,分别接收自己Activity的Module,然后返回自己Activity的Component,在这里又分别创建了SecondActivityComponentImpl和ThirdActivityComponentImpl实例。
再进到这两个内部类中可以看到,真正的注入方法在这里。

@Override
      public SecondActivity inject(SecondActivity secondActivity) {  
        secondActivityMembersInjector.injectMembers(secondActivity);
        return secondActivity;
      }

注意,这里的secondActivityMembersInjector在SecondActivityComponentImpl的初始化方法中创建:

private void initialize() {  
        this.secondActivityMembersInjector = SecondActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
      } 

而provider是在UserComponentImpl中的初始化方法中创建的:

private void initialize() {  
      this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(userModule));
    }

剩下的注入流程和之前的就一样了。inject方法中调用SecondActivity_MembersInjector的injectMembers方法,在这里通过调用Provider的get方法,由provider决定是否需要新建实例,需要时再调到咱们的provide方法拿到真正的实例并返回,不需要时直接返回。
以上是对使用 @SubComponent 注解实现自定义Scope的源码解析。

你可能感兴趣的:(Dagger2 生成代码学习笔记)