【问题标题】:Getting multiple guice singletons of the same type获取相同类型的多个 guice 单例
【发布时间】:2009-08-03 11:53:39
【问题描述】:

你能得到 2 个相同底层类型的单例实例吗?

这在 spring 中显然是微不足道的,因为它基于您附加范围的命名实例,但我在 guice 中看不到关于将类型绑定到实现类的等价物。请注意,我不想绑定到实例,因为相关实例通过 guice 注入了其他依赖项。

【问题讨论】:

    标签: java dependency-injection guice


    【解决方案1】:

    在 Guice 中也很容易!创建两个投标注释,例如 @One@Two,然后

    bind(MySingleton.class).annotatedWith(One.class).toInstance(new MySingleton());
    bind(MySingleton.class).annotatedWith(Two.class).toInstance(new MySingleton());
    

    然后

    @Inject
    public SomethingThatDependsOnSingletons(@One MySingleton s1,
        @Two MySingleton t2) { ... }
    

    【讨论】:

    • 或 @Provides 方法,如果它有依赖关系,我错过了文档的这一位 (code.google.com/docreader/…) 依赖关系可以作为参数传递给方法。在调用方法之前,注入器将执行每个这些绑定。
    • 您不需要将其绑定到实例。同一个类的两个不同注解,在单例范围内,已经创建了两个单独的实例。
    • @Filip,我尝试了您的建议,并收到了两个注释的相同实例。我用bind(MySingleton.class).annotatedWith(One.class).to(MySingleton.class).in(Singleton.class); bind(MySingleton.class).annotatedWith(Two.class).to(MySingleton.class).in(Singleton.class);
    【解决方案2】:

    我想补充 Marcin 的回答,补充说您不必限制自己在这种情况下使用 toInstance() 或提供程序方法。

    以下内容同样有效:

    bind(Person.class).annotatedWith(Driver.class).to(MartyMcFly.class).in(Singleton.class);
    bind(Person.class).annotatedWith(Inventor.class).to(DocBrown.class).in(Singleton.class);
    

    [...]

    @Inject
    public BackToTheFuture(@Driver Person marty, @Inventor Person doc) { ... }
    

    Guice 在实例化 MartyMcFly 和 DocBrown 类时会像往常一样注入依赖项。


    请注意,当您想绑定多个相同类型的单例时,它也可以工作:

    bind(Person.class).annotatedWith(Driver.class).to(Person.class).in(Singleton.class);
    bind(Person.class).annotatedWith(Inventor.class).to(Person.class).in(Singleton.class);
    

    为此,您必须确保 Person 未绑定在 Singleton 范围内,无论是明确地在 Guice 模块中还是使用 @Singleton 注释。更多详情请见this Gist

    编辑: 我作为示例给出的示例代码来自Guice Grapher Test。 查看 Guice 测试是更好地了解如何使用 API 的好方法(这也适用于每个具有良好单元测试的项目)。

    【讨论】:

    • 谢谢 Jesse :) 我用来说明我的观点的示例代码实际上来自对 Guice Grapher 扩展的测试。我认为这很有趣并按原样粘贴。不过,我应该放一个指向源的链接(我现在就这样做)。顺便说一句,我喜欢你的博客,尤其是你在 Guice / Google Collections (publicobject.com) 上的实用文章。我们需要更多像您这样的博客。所以,也谢谢你。
    • @eneveu,您建议您的解决方案是 Marcin 的替代方案。在我看来,您描述的用例与他的不同,因为您假设有两个不同的驱动程序实现类(MartyMcFly、DocBrown),而不是一个具体(驱动程序)类的两个实例。当我尝试在后一种情况下使用这种技术时,我得到两个对同一个单例的引用:bind(MySingleton.class).annotatedWith(One.class).to(MySingleton.class).in(Singleton.class); bind(MySingleton.class).annotatedWith(Two.class).to(MySingleton.class).in(Singleton.class);
    • 它对我有用。也许你用@Singleton 注释了 MySingleton?这是一个包含各种示例和解释的单元测试:gist.github.com/1156593
    • @JeffAxelrod 我以不同的方式阅读示例,MartyMcFlyDocBrown 都扩展了 Person 类,@Driver@InventorBinding Annotation 接口。 Guice FAQ 还显示了Private Modules solution,例如BackToTheFuture 类需要具有特定类型而不是基本类型(即BackToTheFuture(@Driver MaryMcFly driver,...))。
    猜你喜欢
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 2016-09-03
    • 2011-04-21
    • 2015-05-11
    • 1970-01-01
    相关资源
    最近更新 更多