【问题标题】:Two singletons instances with dependency injection (Google Guice)两个带有依赖注入的单例实例(Google Guice)
【发布时间】:2012-06-01 19:02:55
【问题描述】:

我正在开发一个使用依赖注入 Google Guice 框架的项目。

可以将类与单例范围绑定,在 Guice 中为:

bind(Foo.class).to(FooImpl.class).in(Scopes.SINGLETON);

如果FooImpl 类本身是一个真正的单例类:

public class FooImpl implements Foo{
    public static final FooImpl INSTANCE = new FooImpl();
    public static FooImpl getInstance(){...}
    // ...
}

或

public class FooImpl implements Foo{
    private FooImpl instance = null;

    private FooImpl(){...}
    public static FooImpl getInstance(){
         if(instance == null)
             instance = new FooImpl();
         return FooImpl();
         // ...
    }

    // ...
}

因此,可以在项目中声明两个单例,第一个由 Guice 声明,第二个由 getInstance() 传统方式声明。

Google Guice 还可以使用 toInstance() 方法将接口绑定到特定实例。

因此,在 Java 中使用以下声明来绑定 Singleton,而不是与 Singleton 范围绑定,这不是更好的方法:

bind(Foo.class).toInstance(FooImpl.getInstance());

而不是第一个?它更安全吗?这样可以有两个单例实例吗?

使用 Google Guice 声明单例的最佳方式是什么?

【问题讨论】:

    标签: java dependency-injection guice


    【解决方案1】:

    首选您建议的第一种方法:

    bind(Foo.class).to(FooImpl.class).in(Scopes.SINGLETON);
    

    这允许 Guice 根据需要在 FooImpl 中执行依赖注入。在您上次的建议中使用toInstance() 手动绑定到实例时,这是不可能的。

    最后,单例设计模式is an anti-pattern for many reasons。注意这里指的是使用getInstance()等的实现;在应用程序的整个生命周期内拥有一个类的单个实例(例如 Guice 的 SINGLETON 范围内的对象)无论如何都不错。

    有关单例范围的一些使用指南,另请参阅 Guice's page on scopes。

    【讨论】:

    • 我知道 Singleton 是一种反模式,但我不是最初的代码设计者,所以我必须使用它!
    • 但是,使用第一种方式,可能有人会错误地忘记依赖注入并使用新的..创建单例实例。所以在这种情况下,我们应该有两个单例实例,即一个问题(在我的项目中,例如)
    • 通常情况下,您会将实现的可见性 (FooImpl) 限制为包私有左右。因为你是对的:用户不应该自己创建实例。见this link on keeping constructors hidden。如果您坚持使用FooImpl,那么您已经超出了最佳解决方案。我想绑定实例(你的最后一个建议)将是第二好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 2011-01-02
    • 2016-10-23
    相关资源
    最近更新 更多