If singleton is bad!! why spring bean are singletone by default
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.
Is a spring bean created with NEW really a singleton
Spring
guarantees that whatever you do in the method annotated with Bean
annotation it will be done only once. Internal Spring factories will take care about that.
Of course it depends from scope
but by default scope is singleton
. See docs:
- Scopes
- Bean
- Is spring default scope singleton or not?
Small example which should help you to understand how it works:
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
import java.util.Random;
@Configuration
public class SpringApp {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringApp.class);
System.out.println(ctx.getBean(MyClass.class));
System.out.println(ctx.getBean(MyClass.class));
System.out.println(ctx.getBean(MyClass.class));
System.out.println(ctx.getBean(MyClass.class));
}
@Bean
public MyClass getMyClass() {
System.out.println("Create instance of MyClass at " + LocalDateTime.now());
MyClass myClass = new MyClass();
return myClass;
}
}
class MyClass {
private int value = new Random().nextInt();
@Override
public String toString() {
return super.toString() + " with values = " + value;
}
}
prints:
Create instance of MyClass at 2019-01-09T22:54:37.025
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221
com.celoxity.spring.MyClass@32a068d1 with values = -1518464221
When you define bean with scope protoype
@Scope("prototype")
@Bean
public MyClass getMyClass()
App prints:
Create instance of MyClass at 2019-01-09T22:57:12.585
com.celoxity.spring.MyClass@282003e1 with values = -677868705
Create instance of MyClass at 2019-01-09T22:57:12.587
com.celoxity.spring.MyClass@7fad8c79 with values = 18948996
Create instance of MyClass at 2019-01-09T22:57:12.587
com.celoxity.spring.MyClass@71a794e5 with values = 358780038
Create instance of MyClass at 2019-01-09T22:57:12.587
com.celoxity.spring.MyClass@76329302 with values = 868257220
What is the default bean scope if we use @Inject with @Component?
There's no difference between @Inject or @Autowired
two annotations works the same way as Spring has decided to support some JSR-299 annotations in addition to their own
Note JSR-299 is built on top of JSR-330
JSR-299 (Java Contexts and Dependency Injection), with Gavin King as lead, uses JSR-330 as base and enhances it significantly with modularization, cross cutting aspects (decorators, interceptors), custom scopes, or type safe injection capabilities. JSR-299 is layered on top of JSR-330
All spring beans, as @Component
, are by default singletons
singleton bean is quite different from the Singleton pattern as defined in the seminal 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 will ever be created per ClassLoader. The scope of the Spring singleton is best described as per container and per bean. This means that if you define one bean for a particular class in a single Spring container, then the Spring container will create one and only one instance of the class defined by that bean definition. The singleton scope is the default scope in Spring
Why Spring bean is singleton scope?
Stateless beans rules :) If you're not going to hold state data in beans then it's enough to have only one instance of each bean. You should also remember that it's not JVM singletons - just Spring singletons. So you don't have to provide only private constructor and any getInstance() methods.
Quote from Spring documentation:
When a bean is a singleton, only one shared instance of the bean will
be managed and all requests for beans with an id or ids matching that
bean definition will result in that one specific bean instance being
returned.
Only when you have to keep some session details you should use for example session scope.
What is the default bean scope used by Spring Boot?
Spring Boot doesn't decide anything about the bean scope, this is plain Spring framework functionality. Default bean scope is singleton scope (meaning, one instance of that bean in the application).
@Component Spring annotation standard scope
The singleton scope is the default scope in Spring.
This is said here
And also in the current doc you find
singleton
(Default) Scopes a single bean definition to a single object instance per Spring IoC container.
Related Topics
Eclipse Autocomplete (Content Assist) with Facelets (Jsf) and Xhtml
Post Increment Operator Not Incrementing in for Loop
Netbeans How to Set Command Line Arguments in Java
Where Are Generic Types Stored in Java Class Files
Why Do Java If Statement Fail When It Ends in Semicolon
Set Specific Precision of a Bigdecimal
How to Invert the Case of a String in Java
Do We Need Volatile When Implementing Singleton Using Double-Check Locking
Java Bufferedimage Getting Red, Green and Blue Individually
Bouncy Castle:Pemreader => Pemparser
Deserialize Java 8 Localdatetime with Jacksonmapper
Functional Interface That Takes Nothing and Returns Nothing
Spring Choose Bean Implementation at Runtime
Steganography in Lossy Compression (Java)
Gwt: Timer and Scheduler Classes
Getting Nosuchmethoderror:Javax.Servlet.Servletcontext.Getvirtualservername()