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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With