Dagger2中@Scope注解详解

2016年10月17日更新
我认为关于@Scope的作用讲的最好最清晰的一篇,从零开始的Android新项目4 - Dagger2篇,
这里写图片描述


1.Dagger2中@Singleton和自己定义的@PerActivity、@ApplicationScoped等代码上并没有什么区别,

@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationScoped {
}

区别是在如下那种Component依赖的Component的情况下,两个Component的@Scope不能相同,如下例子就是说ApplicationComponent的@ApplicationScoped与WelfareListActivityComponent的@ActivityScoped不相同。既然没什么区别,那为什么还要这么做呢?是因为这样标示可以清晰的区分Component依赖的层次,方便理清我们的代码逻辑层次

@ApplicationScoped
@Component(modules = ContextModule.class)
public interface ApplicationComponent {
    void inject(QJapplication application);
    Context getApplicationContext();
}
@ActivityScoped
@Component(dependencies = ApplicationComponent.class, modules = {PresenterModule.class, ViewModule.class})
public interface WelfareListActivityComponent {
    void inject(WelfareListActivity activity);
}
  1. 有@Scope注解和没@Scope注解的编译时生成代码的区别。
    在编译生成的Dagger…Component的initialize函数代码中我们可以看到如下:
  private void initialize(final Builder builder) {

    this.provideContextProvider = ContextModule_ProvideContextFactory.create(builder.contextModule);

    this.provideWelfareListFragmentProvider =
        DoubleCheck.provider(
            ViewModule_ProvideWelfareListFragmentFactory.create(builder.viewModule));

    this.provideWelfareRepositoryProvider =
        DoubleCheck.provider(
            RepositoryModule_ProvideWelfareRepositoryFactory.create(builder.repositoryModule));
...        
  }

有@Scope类注解的@Provider生成的代码,外层多了一层DoubleCheck.provider(…);没有@Scope类注解的则是直接create一个新的实例。关于DoubleCheck的分析看这里,简单来说就是加了@Scope的Provider,Dagger会缓存一个实例在Dagger…Component中,在Dagger…Component中保持单例,缓存的provide跟随Dagger…Component的生命周期,Dagger…Component被销毁时,provider也被销毁,这就是局部单例的概念,假如你的Dagger…Component是在你应用的application中,则就形成了全局单例。
3.@Scope类注解可以放在什么位置,怎么用?
第一种最常见的用法:即放在@Module中的@provides处和@Component处,这两处可以配合使用。假如如@Component(modules = {PresenterModule.class, ViewModule.class}),如果@Component依赖的某一或多个module中的@provides有@Scope,则@Component也必须有,否则编译时会报错。

@Scope放在@Module和@Inject上的作用还没细研究,代补充…

你可能感兴趣的:(Android)