在SpringMVC中使用单例枚举

在SpringMVC中使用单例枚举,spring,spring-mvc,singleton,Spring,Spring Mvc,Singleton,这是我使用enum的singlton类: public enum MyInstanceFactory { INSTANCE; private SOMEOBJECT; private int countInitialization = 0; private MyInstanceFactory(){ countInitialization++; System.out.println("WOW!! This has been i

这是我使用
enum
的singlton类:

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
的正确值

我的问题是
当spring应用程序启动时,我想做同样的事情,即初始化constructor一次,并多次使用**getSomeobject**。

我看到了,但他们在说

如果它找到具有正确参数的构造函数,不管可见性如何,它都将使用反射将其构造函数设置为可访问。


反射会给singleton类带来问题吗?

如果您需要一个不可颠覆的singleton类(不仅仅是一个被许多其他bean共享的singleton bean,实际上是一个只能实例化一次的singleton类),那么enum方法是一个很好的方法。Spring不会尝试实例化enum本身,因为这真的没有意义;这比仅仅调用私有构造函数要糟糕得多

在这种情况下,要从Spring配置中引用enum实例,您需要做同样的事情;例如:

<util:constant static-field="MyInstanceFactory.INSTANCE" />


在您发布的SO帖子中,您还应该看到Matthew Farwell的答案。这符合你的要求。顺便说一句,我不确定,但Spring不太可能调用私有构造函数。你一定要做个测试来找出答案!是的,当我试图访问它抛出的枚举时,你是对的,没有找到默认构造函数异常意味着私有构造函数不可访问。是的,反射对于传统的单例模式来说是一个问题。
enum singleton模式(您在上面描述过)是防止反射攻击的唯一方法。Spring bean默认为singleton,Spring允许在任何地方注入该singleton,从而使代码单元可测试。为什么要使用这种使代码不稳定的单例反模式,这也是为什么要首先使用依赖注入的主要原因?不,恰恰相反。您应该使SomeObject成为POJO,声明为springbean(使用XML或注释),而不是通过枚举工厂来实例化它,信任Spring只实例化一次这个POJO,并将这个POJO注入到其他需要它的Spring组件中。这就是依赖注入的原理。