我通常使用单例持有者模式创建单例类,如下所示:
public class Foo {
private static final class SingletonHolder {
private static final Foo INSTANCE = new Foo();
}
private Foo(){}
public static final Foo getInstance(){
return SingletonHolder.INSTANCE;
}
}
一切都好。但是,如果我需要注入(inject)一个依赖项来初始化单例对象怎么办?
在这种情况下,我添加了一个方法 initialize
来接收依赖项并且必须仅调用一次:
public class Foo {
private static final class SingletonHolder {
private static final Foo INSTANCE = new Foo();
}
private Foo(){}
public static final void initialize(Dependency d) {
SingletonHolder.INSTANCE.setDependency(d);
}
public static final Foo getInstance(){
return SingletonHolder.INSTANCE;
}
}
我的方法正确吗?还有其他解决方案吗?我知道这取决于程序、我的逻辑等等...但是一般应该如何解决这个问题?
最佳答案
我认为你把事情想得太复杂了。在我工作过的一些地方(包括我现在的地方),我们不会尝试强制执行单例。实际应用程序的所有连接都在一个地方完成,因此如果您搜索构造函数的用法,您应该在 src
中找到一个,并且可能在 test
中找到多个。请参阅下面的代码。
您的方法的一些缺点:
- 你失去了不变性,
Foo
的依赖关系可能会改变 setDependency
和initialize
方法都是生产中的测试代码- 您的构造函数未创建有效的对象,构造函数的后半部分位于
initialize
方法中,您必须记住在调用构造函数后调用该方法 SingletonHolder
是一个样板代码,我不确定为什么不直接声明public static final Foo instance
字段?- 仍然可以使用反射 API 和对象序列化机制创建
Foo
的多个实例
public class Foo {
private final Dependency dependency;
public Foo(Dependency dependency) {
this.dependency = dependency;
}
// ...
}
public class Dependency {
// ...
}
关于java - SIngleton对象初始化和依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33503975/