【问题标题】:Singletons in Dagger 1.xDagger 1.x 中的单例
【发布时间】:2013-07-03 12:07:45
【问题描述】:

在使用 Dagger 时,我发现当我将它注入到任何需要它的地方时,我会得到多个单例实例。我已经用@Singleton 注释了类和提供方法。谁能想到为什么会这样?

编辑:

如果有帮助,我的应用程序的结构与 Dagger 的 GitHub (https://github.com/square/dagger/tree/master/examples/android-activity-graphs) 中的示例应用程序相同。我正在尝试在自定义 Application 类中使用 @Provides 提供基本活动中的 Singleton 和几个第三方类。是因为我在每个活动中都将模块添加到原始对象图中吗?

(PS:我是 Dagger 和 DI 的新手,所以如果您能提供解释以便我学习,我将不胜感激。谢谢。)

【问题讨论】:

    标签: android dependency-injection dagger


    【解决方案1】:

    @Singleton 在 Dagger 1.x 中的行为与您想象的不同。 @Singleton javadoc 中的 JSR-330 规范定义是“每个图一个”,这就是 Dagger 解释它的方式。

    因此,如果您有标记为 @Singleton 的内容,并且它在您的应用程序图中实现(与较短生命周期的图相反),那么每个应用程序都会获得一个实例。

    如果您在用于配置活动图的模块中有一个注解为 @Singleton 的项目(即,从 plus() 操作中使用的模块指定的图部分获得),那么您将获得一个每个活动图。

    如果您需要一个应用程序一次的东西,您需要确保它被创建为应用程序图的一部分。您可以通过以下两种方式之一执行此操作。要么从你的应用程序模块显式地为它提供一个@Provides 方法,要么你可以将它列为应用程序模块中@Module(injects=...) 中的一个类。

    (如果您没有用@Singleton 标记它,那么您将在每个注射部位获得一个。)

    所以请记住,由 plus() 创建的图被视为一个单独的图,它指向生成它的图并包装它,可以访问其中的实例,但不是同一个图。

    注意 - Dagger 2.x 改进了这一点,并支持自定义范围注释,尽管机制相似,每个范围注释一个图(组件),在更宽/更窄的生命周期图之间具有父/子关系

    【讨论】:

    • 感谢您解决这个问题。当您说规范时,您指的是 JSR330 吗?
    • @ChristianGruber 这如何应用于父图的各种子图中使用的单例注入构造函数?这是否意味着使用该类的每个图一个,除非它已经存在于父图中?
    • 有点。如果一切都“及时”绑定,那么是的,就是这样。如果您使用标记为 Singleton 的事物,它将在首先请求它的图形中创建。因此,如果您希望它在父图(或根图)中创建,您需要通过在 @Provides 方法中提供它或通过在更长寿命图中模块注释的injects= 属性。
    • 酷!我认为@Provides 很笨拙而且不干,不知道injects= 也有用,会使用它。
    • @vinc3m1 一种更干燥的方法是将@Singleton 放在项目的类定义中,而不是放在@Prodices 块或@Modules{inject=...} 规范中作为类级别@987654333 @ 注释将其限定为图形的单例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多