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);
}

运行结果如下:


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<UserModel> provideUsersProvider;
  private MembersInjector<MainActivity> 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<UserModel> provideUsersProvider;
private MembersInjector<MainActivity> 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<UserModel> {
  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<UserModel> 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<MainActivity> {
  private final MembersInjector<AppCompatActivity> supertypeInjector;
  private final Provider<UserModel> userProvider;

  public MainActivity_MembersInjector(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserModel> 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<MainActivity> create(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserModel> 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
   *
   * <p>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 <T> MembersInjector<T> noOp() {
    return (MembersInjector<T>) NoOpMembersInjector.INSTANCE;
  }

  private static enum NoOpMembersInjector implements MembersInjector<Object> {
    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).
   *
   * <p>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 <T> MembersInjector<T> delegatingTo(MembersInjector<? super T> delegate) {
    return (MembersInjector<T>) 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<T> implements Provider<T> {
  private static final Object UNINITIALIZED = new Object();

  private final Factory<T> factory;
  private volatile Object instance = UNINITIALIZED;

  private ScopedProvider(Factory<T> 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 <T> Provider<T> create(Factory<T> factory) {
    if (factory == null) {
      throw new NullPointerException();
    }
    return new ScopedProvider<T>(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());
    }
}

运行一下。


Screenshot_2017-02-09-09-48-06.png

Screenshot_2017-02-09-09-48-10.png

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<UserModel> 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<SecondActivity> 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<ThirdActivity> 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的源码解析。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容