0

Here is my singlton class using 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; }
}

Now I am calling it like inside MVC controller

Session cqlSession = MyInstanceFactory.INSTANCE.getSomeobject();

In this way it calls constructer only first time and next and onwards it return the correct value for SOMEOBJECT.

My question is I want to do the same thing when a spring application start i.e. initializing contructor once and use **getSomeobject** multiple times.

I saw THIS SO ANSWER but here they are saying

If it finds a constructor with the right arguments, regardless of visibility, it will use reflection to set its constructor to be accessible.

Will reflection create problem for a singlton class?

Community
  • 1
  • 1
Manish Kumar
  • 10,214
  • 25
  • 77
  • 147
  • 1
    In the SO thread you posted, you should also see Matthew Farwell's answer. That fits your requirement. BTW, I am not sure but it looks unlikely that Spring will call private constructors. You should definitely do a test to find out! – arahant Feb 03 '14 at 07:00
  • yes you are right when i tried to access my enum it throws `No default constructor found;` exception means private constructor is not accessble. – Manish Kumar Feb 03 '14 at 07:20
  • Yes, reflection is a problem for the traditional singleton pattern. The `enum singleton pattern` (which you describe above) is the only way to prevent a reflection attack. – jax Feb 03 '14 at 10:09
  • How can i implement it in spring MVC scenario – Manish Kumar Feb 03 '14 at 11:02
  • 1
    Spring beans are singletons by default, and Spring allows injecting that singleton anywhere you like, making your code unit-testable. Why would you use this singleton anti-pattern which makes the code untestable, and is the main reason why dependency injection is used in the first place? – JB Nizet Feb 03 '14 at 12:35
  • @Nizet so are u trying to say that i should use `MyInstanceFactory.INSTANCE.getSomeobject();` anywhere in my spring app instead of initializing it at the first time from xml. – Manish Kumar Feb 03 '14 at 13:02
  • 2
    No. Exactly the reverse. You should make SomeObject a POJO, declared as a Spring bean (using XML or annotations), not go through an enum factory to instantiate it, trust Spring to instantiate this POJO only once, and inject this POJO in the other Spring components that need it. That's the principle of dependency injection. – JB Nizet Feb 03 '14 at 15:51
  • @Nizet Yes i agree I was reading throughout that `enum` is thread safe,serializable and it avoid reflection. But I thnk if i initialize a bean from xml then it will also enjoy thread safety as it will set the value just at starting of app.right?? – Manish Kumar Feb 03 '14 at 16:26

1 Answers1

0

If you need a non-subvertible singleton class (not just a singleton bean that's shared by many other beans, but actually a singleton class where the class can only ever be instantiated once), then the enum approach is a good one. Spring won't try to instantiate the enum itself, because that really makes no sense; that would be a much more extremely broken thing to do than merely calling a private constructor.

In that case, to refer to the enum instance from Spring configuration, you do the same thing as for any other static constant; for example:

<util:constant static-field="MyInstanceFactory.INSTANCE" />
Community
  • 1
  • 1
ruakh
  • 175,680
  • 26
  • 273
  • 307