This question already has answers here:
Singleton design pattern vs Singleton beans in Spring container
(11 answers)
Closed 6 years ago.
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.
Related
This question already has answers here:
Singleton design pattern vs Singleton beans in Spring container
(11 answers)
Closed 3 years ago.
Is it common that in Java programming using Spring bean to control singleton instance instead of making a class with the singleton pattern?
It depends. If you need an utility class, which has no dependencies and that just provide a bunch of commons methods, I think it is quick and straightforward to build your own singleton.
But if you want to build a business class which needs to be injected with other dependencies, and probably, you want to define interfaces to avoid coupling between classes, I think Spring (or other DI frameworks) are better (easier) than build your own singleton.
These are the differences :
JVM handles the lifecycle of Singleton pattern classś object where Spring context handles life cycle of Spring singleton bean.
Singleton pattern classś object will be single for whole JVM where if you have multiple SpringContext in same JVM you can have multiple objects of it.
It depends on how loosely you interpret the Singleton pattern.
In my interpretation, Singleton implies that there is exactly one instance per given context. The context is usually the JVM (the ClassLoader, actually), as that is the easiest to implement with plain Java code, but nothing stops me from mapping the pattern to different contexts, one of them being Spring's ApplicationContext.
According to this definition, one could argue that the "request" and "session" scopes also hold singleton objects, just with a narrower scope.
See also this previous answer of mine, where I go into more detail.
Simply, when you use spring bean singleton, you will have one instance per spring container.
However, when you implement the singleton pattern by yourself (java based design pattern in our case), you will have one instance per java class loader.
During reading the Spring Framework's documentation I came across the following:
Spring’s concept of a singleton bean differs from the Singleton
pattern as defined in the Gang of Four (GoF) patterns book. The GoF
Singleton hard-codes the scope of an object such that one and only one
instance of a particular class is created per ClassLoader. The scope
of the Spring singleton is best described as per container and per
bean.
I don't understand why per ClassLoader? Why don;t per the entire application or in the Context they are considered to be the same things?
Because in the traditional singleton, you have a static variable in the Singleton class to keep the single instance. However since you can load the same class using multiple ClassLoaders, those will have their own static variables and are free to create their own instance.
In most cases this is not a problem anyway.
Singleton Pattern maintains the instance at Spring Container Level, while the Singleton Design Pattern maintains it at Class Loader Level.
Is any other difference?
Next, I still think there the above reason in not a valid reason. It is just the matter of fact that one Application Context/Container is loaded in one Class Loader only. Thus technically there is no difference.
Is that correct or I am missing something?
Ref: Singleton design pattern vs Singleton beans in Spring container
Well, the real difference is not around class loading, but it's about the design principle. Singleton pattern has it's own limitations. It exposes an object globally as well as it's difficult to test. But, singleton through DI framework like Spring or Guice is free from those problems.
This SO thread may help you to understand. As well as Google-singleton-detector and Misko Hevery's blog are also interesting read.
Using a "real" singleton is more limiting in the sense that you are then bound to be able to create only a single instance of that class (within a classloader).
If you use Spring singleton-scoped beans, you can create as many "singleton" instances of that class you like (as long as the bean class is not a real singleton).
Hence they are not technically the same thing.
This is mostly the name that these two have in common. Singleton pattern ensures a class has only one instance, while Spring's singleton bean scope just instructs container to use the single instance of a bean during dependency injection, the bean can be any class with no restrictions.
A spring singleton ensures that only one instance of the object is created as long as the object is created using spring framework. On the contrary implementing the singleton pattern ensures that only one instance of the object is present.
I have seen code where objects were defines as singleton in spring configuration. The singleton object was some times created using spring DI and other times using new operator.
Hence caution is required to ensure that such kinds of abuses are not made and single instance of singletons be maintained.
Singleton pattern is described at per class loader level.
Singleton bean scope is per spring container.
http://www.javabench.in/2012/04/difference-between-singleton-design.html
It's common to have an object used application wide.
What are the different patterns / models / ways to share an object through an application?
Is defining a "main class", then setting a member variable and extending all other classes from this "main class" a good way? Is creating a static class probably the better and cleaner way? What's your prefered pattern?
It's common to have an object used application wide. What are the different patterns / models / ways to share an object through an application?
One common way is to use the singleton pattern. I would avoid that though.
Is defining a "main class", then setting a member variable and extending all other classes from this "main class" a good way
Absolutely not. Aside from anything else, if it's an instance variable then it wouldn't be "shared" with instances of your other classes anyway. It's also a complete abuse of inheritance which would certainly bite you hard in any application of significant size - your other classes wouldn't logically have an inheritance relationship with your "main" class, would they? As a general rule, inheritance should only be used when it's really appropriate - not to achieve a quick fix.
What's your prefered pattern?
Dependency injection. When your application starts up, create all the appropriate objects which need to know about each other, and tell them (usually in the constructor) about their dependencies. Several different objects can all depend on the same object if that's appropriate. You can use one of the many dependency injection frameworks available to achieve this easily.
Dependency injection generally works better than using singletons because:
The class itself doesn't know whether or not the dependency is actually shared; why should it care?
Global state makes unit testing harder
Each class makes its dependencies clearer when they're declared - it's then easier to navigate around the application and see how the classes relate to each other.
Singletons and global factories are more appropriate when they're for things like logging - but even then, it means it's relatively hard to test the logging aspects of a class. It's a lot simpler to create a dependency which does what you need it to, and pass that to the object under test, than it is to add ways of messing around with a singleton (which usually remains "fixed" after initialization).
If you use a framework like Spring which has dependency injection, you can get all the benefits of "global" objects for free without needing to explicitly define them. You just create a reference to them in your application context and you can inject them into any object you'd like without worrying about issues with synchronizing.
Singleton pattern, AFAIK the preferable way in software engineering.
I believe what you are looking for is the Singleton Pattern. With this pattern you are ensured that only one instance of a class can be created in memory.
Example:
public class mySingletonClass {
private static mySingletonClass singleObject;
// Note that the constructor is private to prevent more than one
//instance of the class
private SingletonObjectDemo() {
// Optional Code
}
public static mySingletonClass getSingletonObject() {
if (singleObject == null) {
singleObject = new mySingletonClass();
}
return singleObject;
}
}
That said, you should try to avoid using it; but there are some acceptable cases, one of which is here.
Can you briefly explain: What mainly differs Dependency Injection from Factory Design pattern?
Additionally: Is it possible to demonstrate the difference very simply by a code example?
Thanks
With Factory (or any other Creation pattern), the caller has to know how to get the object and has to "explicitly" ask for it before consuming it.
Car car = CarFactory.getCarByModel(LUXURY);
Whereas when using DI, the responsibility to pass the desired object is delegated to some external (container mostly) entity which knows how to create the object (by reading the config already defined) and make it available to the caller silently.
Car car = getCar();
void setCar(Car car){..} // container sets the car fromoutside
The factory pattern is typically useful to repeatedly create instances of an object with possibly complex instantiation logic. This way, your classes knows of the factory and requests instances.
Dependency injection goes one step further to completely abstract away instantiation logic as far as your classes are concerned. All your code needs to care about is to declare the dependencies they need, without bothering where they come from.
For a nice in-depth guide, see Inversion of Control Containers and the Dependency Injection pattern.
Same goals are achieved with both patterns, it's just that with the factory design pattern you have to write code whereas with DI you use an existing DI framework to do the job for you and simply do the configuration of the dependencies. With the factory pattern you have to write factories for you classes.