java单例对象初始化和依赖项注入
我通常使用singleton holder模式创建singleton类,如下所示:
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;
}
}
一切都好。但是,如果我需要注入一个依赖项来初始化singleton对象呢
在这种情况下,我添加了一个方法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;
}
}
我这样做对吗?还有别的解决办法吗?我知道这取决于程序,我的逻辑等等。。。但这个问题一般应该如何解决
# 1 楼答案
我认为你把它复杂化了。在我工作过的一些地方(包括我现在工作的地方),我们不试图强制执行单身。实际应用程序的所有连接都在一个地方完成,因此如果您搜索构造函数的用法,您应该在
src
中找到一个,在test
中可能找到多个。请参阅下面的代码您的方法有几个缺点:
Foo
的依赖关系可以改变setDependency
和initialize
方法都是生产中的测试代码initialize
方法中,您必须记住在调用构造函数后调用该方法SingletonHolder
是一个锅炉板代码,我不确定您为什么不直接声明public static final Foo instance
字段李>Foo
的多个实例# 2 楼答案
这种方法的问题在于
initialize
方法可以多次调用,并且代码中没有任何迹象表明正在使用线程安全性处理依赖项的设置如果您不介意的话,那么您的懒惰初始化习惯用法就可以了
否则,您可以抛出一个
IllegalStateException
,或者在单例实例中多次设置依赖项时不执行任何操作编辑
正如Andy Thomas所说,您也没有检查在调用
getInstance
之前是否设置了依赖项,或者至少您的代码没有显示它