【发布时间】:2014-02-26 14:01:43
【问题描述】:
这是我使用enum 的单例类:
public enum MyInstanceFactory {
INSTANCE;
private SOMEOBJECT;
private int countInitialization = 0;
private MyInstanceFactory(){
countInitialization++;
System.out.println("WOW!! This has been initialized: ["+countInitialization+"] times");
SOMEOBJECT = SOMETHING
}
public Session getSomeobject(){ return SOMEOBJECT; }
}
现在我像在 MVC 控制器中一样调用它
Session cqlSession = MyInstanceFactory.INSTANCE.getSomeobject();
以这种方式,它只在第一次和下一次调用构造函数,然后返回正确的 SOMEOBJECT 值。
我的问题是I want to do the same thing when a spring application start i.e. initializing contructor once and use **getSomeobject** multiple times.
我看到了THIS SO ANSWER,但他们在这里说
If it finds a constructor with the right arguments, regardless of visibility, it will use reflection to set its constructor to be accessible.
反射会给单例类带来问题吗?
【问题讨论】:
-
在您发布的 SO 线程中,您还应该看到 Matthew Farwell 的回答。这符合你的要求。顺便说一句,我不确定,但 Spring 似乎不太可能调用私有构造函数。你绝对应该做一个测试来找出答案!
-
是的,当我尝试访问我的枚举时,你是对的,它抛出
No default constructor found;异常意味着私有构造函数不可访问。 -
是的,反射是传统单例模式的一个问题。
enum singleton pattern(您在上面描述的)是防止反射攻击的唯一方法。 -
Spring bean 默认是单例,Spring 允许在任何你喜欢的地方注入单例,使你的代码可单元测试。为什么要使用这种使代码无法测试的单例反模式,这也是首先使用依赖注入的主要原因?
-
没有。恰恰相反。您应该使 SomeObject 成为 POJO,声明为 Spring bean(使用 XML 或注释),而不是通过枚举工厂来实例化它,相信 Spring 只实例化这个 POJO 一次,并将这个 POJO 注入其他需要它的 Spring 组件中.这就是依赖注入的原理。
标签: spring spring-mvc singleton