5

What is so bad about singletons?

It has been explained so clearly that the Singleton design pattern violates multiple best practices. Then why are spring beans singleton by default? Doesn't this design lead to the same violations indirectly?

Community
  • 1
  • 1
Niru
  • 439
  • 5
  • 14
  • 9
    There's a difference between a *type* enforcing that it's a singleton, and a framework *deciding to provide a single instance to all consumers*. For example, the former makes testing hard - the latter doesn't. – Jon Skeet Jan 06 '17 at 10:10
  • 3
    Hi Niru, this information can be found here: http://stackoverflow.com/questions/2637864/singleton-design-pattern-vs-singleton-beans-in-spring-container – pandaadb Jan 06 '17 at 10:13
  • 3
    Singletons are not bad. Using them when its not necessary is bad. – Alexandru Severin Jan 06 '17 at 10:14
  • The link you shared is itself a debate. Read the comments. It doesn't mean singleton is so bad :) – Ramanujan R Jan 06 '17 at 10:14
  • @pandaadb I have gone through that discussion they say spring singleton is singleton for a context – Niru Jan 06 '17 at 10:16
  • Had a hard time understanding singleton violets! – anacron Jan 06 '17 at 10:17
  • @JonSkeet I did't get you can you explain in details how exactly. – Niru Jan 06 '17 at 10:17
  • 3
    Basically what Jens has put in his answer.. – Jon Skeet Jan 06 '17 at 10:18
  • @AlexandruSeverin Ya that's what my question why should spring framework uses singleton by default even if it is not necessary. – Niru Jan 06 '17 at 10:19
  • @pandaadb Ok your looking in creating another instance of the class, what about memory - lifetime application? – Niru Jan 06 '17 at 10:21
  • 2
    It's just a badly chosen name by Spring. Spring's `@Singleton` effectively follows the "Just create one" pattern. See also a.o. http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne. Java EE has much better scope name for those beans: `@ApplicationScoped`. – BalusC Jan 06 '17 at 10:29
  • Although this question is a duplicate, I think it's worded better than the old one and crucially Jens' answer is clearer and much better than any answer in the original question. According to [this post on meta](http://meta.stackoverflow.com/a/252017/889583), it may be better to keep this question open. Unless there's a way to migrate Jens' answer to the original question? – daiscog Jan 06 '17 at 10:47
  • Singletons are good, static singletons are bad - as a general rule static should only be used for constants and immutable objects. – Klaus Groenbaek Jan 06 '17 at 10:54

2 Answers2

14

The singleton pattern and a spring singleton have very little in common. Actually the only thing is probably:

There is just one instance at runtime in production

Let's go through the critic of the pattern from the answer you linked to:

They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.

With Spring you are doing the exact opposite. You're just saying: "I need one of those, without caring where it comes from."

They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.

Again: Spring does the exact opposite: you code a normal pojo and then you configure in your Spring configuration, what lifecycle it shall have.

They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.

With Spring, nothing stops you to use a different instance for each test.

They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

Yes they can carry state around for the lifetime of the application, but since you can choose to change the lifecycle or the implementation in tests (or different instances of your application), tests stay independent from each other.

All this is really not specific to Spring but is true for probably all mature dependency injection frameworks, and even when you choose to do it manually.

Nicolai Parlog
  • 36,673
  • 16
  • 109
  • 236
Jens Schauder
  • 65,795
  • 24
  • 148
  • 294
5

Spring Singletons are not really Singletons as we know them from the GOF design pattern. They give you that feeling, because there will be a single bean for a IoC container (Bean Factory).

Meaning you can instantiate a class that there is a singleton bean created for it.

You can also have 2 singleton beans from the same class.

So, the 'singularity' is in the concept of the bean in the the bean factory, and not a class.

Example:

@Configuration
public class AppConfig {

    @Bean(name = "a")
    public MyBeanClass a() {
        return new MyBeanClass();
    }

   @Bean(name = "b")
    public MyBeanClass b() {
        return new MyBeanClass();
    }
}

So, you will have 2 singleton beans of class MyBeanClass. And MyBeanClass is not a singleton by design pattern.

galusben
  • 4,833
  • 3
  • 23
  • 45