【问题标题】:Using Singleton enum in Spring MVC在 Spring MVC 中使用单例枚举
【发布时间】: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


【解决方案1】:

如果您需要一个不可颠覆的单例类(不仅仅是一个由许多其他 bean 共享的单例 bean,实际上是一个单例 class,其中该类只能被实例化一次),那么枚举方法是一个很好的方法。 Spring 不会尝试实例化枚举本身,因为这真的没有意义;与仅仅调用私有构造函数相比,这将是一件更加糟糕的事情。

在这种情况下,要从 Spring 配置中引用枚举实例,您可以执行相同的操作 as for any other static constant;例如:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 2012-01-30
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多