我在@Scope注释上阅读了很多材料,但仍然没有完全理解我所知道的是否正确。
有人可以解释@Scope的确切内容吗?在哪里使用?它是如何使用的?
仅在定义组件时使用吗?
也是这样定义的范围?:
@Scope
public @interface SomeScope {
}
像这样使用?:
@SomeScope
@Component(modules = {
HeaterModule.class,
PumpModule.class
})
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
CoffeeMaker maker();
}
答案 0 :(得分:2)
Java EE应用程序范围的定义说明如下:
对于使用注入另一个bean类的bean的Web应用程序, bean需要能够在持续时间内保持状态 用户与应用程序的交互。定义此状态的方法 是给豆子一个范围。
让它与Android联系起来。范围对范围提供者提供的依赖关系生命周期施加了某些限制。
例如,假设我们希望从@Singleton
d组件获得@ActivityScope
依赖关系。只要活动,该组件就会存在。一旦活动被销毁并再次创建,我们的组件就会相应地实例化,并且我们的“@ Singleton'依赖性也会再次创建。
总结一下,我们的@Singleton
依赖项与它们关联的@Components
一样长 - 这是我认为最实用的解释。
在内部,一旦Dagger在具有指定范围的@Component
提供方法中通知,它就会为依赖项提供创建ScopedProvider。否则,将创建Factory。
ScopedProvider
的get方法是一种双重检查单例方法:
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;
}
要查看实用的@Scope
用法,您可以查看我的一个示例:
https://github.com/dawidgdanski/AccountAuthenticatorExample
希望,这在某种程度上是有帮助的。
编辑1 : @Fshamri提供的文章解释得更好。
编辑2 :
让我们考虑以下结构:
组件:
@ActivityScope //Dagger ignores the annotation put atop the @Component. I put it there just for readability
@Component(dependencies = DependencyGraph.class,
modules = {ActivityModule.class})
public interface ActivityComponent {
void inject(MainActivity mainActivity);
void inject(SignUpActivity signUpActivity);
void inject(SignInActivity signInActivity);
提供依赖项的模块:
@Module
public class ActivityModule {
private final Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
@Provides
@ActivityScope
MainView provideMainView() {
return (MainView) activity;
}
@Provides
SignInView provideSignInView() {
return (SignInView) activity;
}
}
@ActivityScope扩展了@Scope注释 - Dagger解释它与@Singleton的解释方式相同。 ActivityModule
提供了2次观看:@ActivityScope
d MainView
和SignInView
没有任何范围。在编译期间,Dagger的注释处理器为两个视图创建Provider s。 MainView&和SignInView生成的Provider之间的区别在于MainView Dagger生成ScopedProvider
(因为我们明确地请求这种提供者@ActivityScope
)而对于SignInView
Dagger会定期生成Factory
个提供商。
ScopedProvider的合同如上所示。但是,Factory
提供商的合同看起来如下:
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class ActivityModule_ProvideSignInViewFactory implements Factory<SignInView> {
private final ActivityModule module;
public ActivityModule_ProvideSignInViewFactory(ActivityModule module) {
assert module != null;
this.module = module;
}
@Override
public SignInView get() {
SignInView provided = module.provideSignInView();
if (provided == null) {
throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
}
return provided;
}
public static Factory<SignInView> create(ActivityModule module) {
return new ActivityModule_ProvideSignInViewFactory(module);
}
}
结论:
1. ScopedProvider
是一种经典的复核单身模式。它保证只创建一个依赖项实例。
2. Factory
的{{1}}方法只是从模块中分配依赖项,这意味着它可以在每次请求时分发新的依赖项实例(事实上,在示例中,Activity只转换为SignInView,它仍然给我们一个实例,但这是我的例子中的复制粘贴逻辑)。
3. Dagger关注@Scopes以及@Modules中的提供方法,而不是@Components。
我鼓励您下载示例并构建项目,然后查看生成的get()
组件和模块的合同。
希望现在更容易理解。
答案 1 :(得分:1)
在Dagger 2中,范围机制关注保持单个实例 类,只要其范围存在。在实践中,它意味着实例 @ApplicationScope中的作用域与Application对象一样长。 只要活动存在,@ ActivityScope就会保留引用(for 例如,我们可以在所有类之间共享任何类的单个实例 此活动中托管的片段)。在短期内,我们“本地化 单身人士“只要与范围本身一样长寿。