In this post, we will discuss about various bean scopes and their differences.
Bean scopes
There are seven bean scopes Spring supports out of which five are only available if your ApplicationContext
is web-aware.
# | Scope | Explanation |
---|---|---|
1 | singleton | There will be single object of the bean per Spring IoC Container (Default). |
2 | prototype | Scope beans to any number of object instances. Every time you get object of prototype bean from context, it will be brand new. |
3 | request | Scope of the bean definition mapped to the lifecycle of HTTP Request. This is only available web-aware ApplicationContext . |
4 | session | Scope of the bean definition mapped to the lifecycle of HTTP session. This is only available to web-aware ApplicationContext . |
5 | globalSession | Scope of the bean definition mapped to the lifecycle of HTTP session usually used within Portlet context. This is only available to web-aware ApplicationContext . |
6 | application | Scope of the bean definition mapped to the ServletContext . This is only available to web-aware ApplicationContext . |
7 | websocket | Scope of the bean mapped to the lifecycle of Websocket . This is only available to web-aware ApplicationContext . |
Singleton Vs Prototype
Let's see a example which shows the difference between Singleton and Prototype scope for bean.
public class Dictionary { private Listwords; public Dictionary() { words = new ArrayList<>(); } public void addWord(String word) { this.words.add(word); } public int totalWords() { return this.words.size(); } @Override public String toString() { return words.toString(); } }
We first defined a class Dictionary
.
Singleton scope
There will be only one shared instance of singleton bean per context and all request for that bean definition will end up returning the same object by the container.
@Configuration public class ScopeConfig { @Bean(name = "singletonDictionary") @Scope("singleton") //you can omit the scope by default it is singleton Dictionary singletonDictionary() { return new Dictionary(); } }
We created a configuration class ScopeConfig
. We created a bean Dictionary
. @Scope
annotation is used to mark the scope of the bean to singleton. If we don't define any scope then by default it is considered singleton scoped bean.
public class App { private static final Logger logger = Logger.getLogger(App.class.getName()); public static void main(String[] args) { try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);) { Dictionary singletonDictionary = context.getBean("singletonDictionary", Dictionary.class); logger.info("Singleton Scope example starts"); singletonDictionary.addWord("Give"); singletonDictionary.addWord("Take"); int totalWords = singletonDictionary.totalWords(); logger.info("Need to have two words. Total words are : " + totalWords); logger.info(singletonDictionary.toString()); singletonDictionary = context.getBean("singletonDictionary", Dictionary.class); logger.info("Need to have two words. Total words are : " + totalWords); logger.info(singletonDictionary.toString()); logger.info("Singleton Scope example ends"); } } }
When we run above snippet, it will generate output like below.
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: Singleton Scope example starts Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: Need to have two words. Total words are : 2 Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: [Give, Take] Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: Need to have two words. Total words are : 2 Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: [Give, Take] Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: Singleton Scope example ends
From output, we can analyse that when we got object of singletonDictionary again from context, it contained the previous added values.
Prototype scope
Prototype scope of bean results in the creation of a new bean instance every time a request for that specific bean is made.
@Configuration public class ScopeConfig { @Bean(name = "prototypeDictionary") @Scope("prototype") Dictionary prototypeDictionary() { return new Dictionary(); } }
We created a configuration class ScopeConfig
. We defined a bean prototypeDictionary. We used @Scope
annotation to mark its scope as prototype.
public class App { private static final Logger logger = Logger.getLogger(App.class.getName()); public static void main(String[] args) { try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);) { Dictionary prototypeDictionary = context.getBean("prototypeDictionary", Dictionary.class); logger.info("Prototype scope example starts"); prototypeDictionary.addWord("Give 2"); prototypeDictionary.addWord("Take 2"); logger.info("Need to have two words. Total words are: " + prototypeDictionary.totalWords()); logger.info(prototypeDictionary.toString()); prototypeDictionary = context.getBean("prototypeDictionary", Dictionary.class); logger.info("zero word count. Total words are: " + prototypeDictionary.totalWords()); logger.info(prototypeDictionary.toString()); } } }
The above code snippet generated below output.
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: Prototype scope example starts Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: Need to have two words. Total words are: 2 Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: [Give 2, Take 2] Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: zero word count. Total words are: 0 Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main INFO: []
From the output logs, you can clearly see that when we got prototypeDictionary object again from context then it returned a new object and there was no previously added words in it.
When to use Singleton and Prototype
Use prototype scope for all stateful beans and singleton scope for stateless beans.
This is all about bean scopes. I hope you find this post informative. You can find the example code on Github.
Good start. I think you may wanna quote real life examples of when to use singleton or prototype. And may be the problems which me arise if we don't pay heed to this.
ReplyDelete