Spring bean scopes example
In Spring, bean scope is used to decide which type of bean instance should be return from Spring container back to the caller.
5 types of bean scopes supported :
- singleton – Return a single bean instance per Spring IoC container
- prototype – Return a new bean instance each time when requested
- request – Return a single bean instance per HTTP request. *
- session – Return a single bean instance per HTTP session. *
- globalSession – Return a single bean instance per global HTTP session. *
In most cases, you may only deal with the Spring’s core scope – singleton and prototype, and the default scope is singleton.
P.S * means only valid in the context of a web-aware Spring ApplicationContext
Singleton vs Prototype
Here’s an example to show you what’s the different between bean scope : singleton and prototype.
package com.mkyong.customer.services;
public class CustomerService
{
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
1. Singleton example
If no bean scope is specified in bean configuration file, default to singleton.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="customerService"
class="com.mkyong.customer.services.CustomerService" />
</beans>
Run it
package com.mkyong.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.customer.services.CustomerService;
public class App
{
public static void main( String[] args )
{
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});
CustomerService custA = (CustomerService)context.getBean("customerService");
custA.setMessage("Message by custA");
System.out.println("Message : " + custA.getMessage());
//retrieve it again
CustomerService custB = (CustomerService)context.getBean("customerService");
System.out.println("Message : " + custB.getMessage());
}
}
Output
Message : Message by custA
Message : Message by custA
Since the bean ‘customerService’ is in singleton scope, the second retrieval by ‘custB’ will display the message set by ‘custA’ also, even it’s retrieve by a new getBean() method. In singleton, only a single instance per Spring IoC container, no matter how many time you retrieve it with getBean(), it will always return the same instance.
2. Prototype example
If you want a new ‘customerService’ bean instance, every time you call it, use prototype instead.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="customerService" class="com.mkyong.customer.services.CustomerService"
scope="prototype"/>
</beans>
Run it again
Message : Message by custA
Message : null
In prototype scope, you will have a new instance for each getBean()
method called.
3. Bean scopes annotation
You can also use annotation to define your bean scope.
package com.mkyong.customer.services;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope("prototype")
public class CustomerService
{
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Enable auto component scanning
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="com.mkyong.customer" />
</beans>
Hi
Thank you for this great post.
Why application scope isn’t mentioned, like request and session, it return a single bean instance per global lifecycle of a ServletContext.
Could you please share the use case with example of prototype bean scope.
Please help me
I am new spring mvc user. In controller i call a singleton bean like that:
@RequestMapping(value = “/student”, method = RequestMethod.GET)
public ModelAndView student( @RequestParam(required=false) String name) {
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {“mvc-dispatcher-servlet.xml”});
Student student = (Student)context.getBean(“student”);
if(name!=null&&name.length()>1){
student.setName(name);
}
System.out.println(“name:”+student.getName());
return new ModelAndView(“result”, “student”, student);
}
The first time, i enter url in browser: http://localhost:8080/example/student?name=myname
The system print result like that: name:myname=> it’s ok
The second time, i enter url in browser: http://localhost:8080/example/student
The system print result like that: name:null
Why? you said that a single bean instance be created for every request?
So the first time the name of student was set is “myname”. The second time, when i request again, if a single bean instance was created, the name of student must be “myname”, because it was set in first time request?But in my case, the second time request, seem that a new bean instance be created? So the name value is null
Thanks very much
The problem as below:
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {“mvc-dispatcher-servlet.xml”});
Spring singleton scoped bean in per IoC container
I read somewhere Singleton Bean Scope – single bean instance per Spring IOC container. i.e. we can multiple bean defination’s but for each bean defination it will be singleton per spring container .
e.g.
here in above case, we will have two bean instances – one is test and another is test2
for below code –
abc object1 =(abc)applicationContext.getBean(“test”);
abc object12 =(abc)applicationContext.getBean(“test”);
we will get two instance of test bean defination. each of singleton type. so i update value of object1 and then it will reflect in object2 also.
abc object1 =(abc)applicationContext.getBean(“test”);
abc object12 =(abc)applicationContext.getBean(“test2”);
in this code, we will have two different instances of seperate bean instance. so If I update object1 property, it will not reflect in object2’s property.
Code is using Context to instantiate two beans of same class: test & test2 both them being Singleton, which is still holds Default Singleton Definition of “One Bean per IOC container”
Bean means recipe defined in the config file, used to create Objects.
“When you create a bean definition what you are actually creating is a recipe for creating actual instances of the class defined by that bean definition. The idea that a bean definition is a recipe is important, because it means that, just like a class, you can potentially have many object instances created from a single recipe.”
From
http://stackoverflow.com/a/17193458/452708
Hi ,
Can you please share some examples for bean scope request and session.
it really clear my doubt between http scope and prototype scope that i have thing before.
excellent article
great la
YEAH!! GREAT MEN!!! 🙂
Good tutorials!
valuable links too I see in comments. Thank you folks.
but where are we setting message property values in code eg singleton case? 🙂
Gracias mkyong, excelentes informacion
You saved my life man!!! 🙂
How do you access the annotation defined bean?
I followed the above steps to make the CustomerService class @Service and @Scope(“prototype”). However, in the App.java’s main method I use the same CustomerService custA = (CustomerService)context.getBean(“customerService”);
custA.setMessage(“Message by custA”);
System.out.println(“Message : ” + custA.getMessage());
It gives me the runtime exception : org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘CustomerServiceAnnotation’ is defined
After second thought, looks like ClassPathXmlApplicationContext is not appropriate to be context for annotation bean. Hence context.getBean(“customerService”); does not make any sense. So which context class should I use in this case?
Many thanks
You have to use : AnnotationConfigApplicationContext instead of ClassPathXmlApplicationContext. This will solve your problem
Great explanation sire .
This link clarifies the use of
and
with a good simple example:
http://stackoverflow.com/questions/7414794/difference-between-contextannotation-config-vs-contextcomponent-scan
This link clarifies the use of and
with a good simple example:
http://stackoverflow.com/questions/7414794/difference-between-contextannotation-config-vs-contextcomponent-scan
another Scope which is thread
http://abdennour-insat.blogspot.com/2012/11/spring-bean-thread-scope.html
Thanks)
hi young good job .can u provide GWT And hadoop tutorials
Hi,
What if I want to dispose a singleton scope bean. is that possible?
thanks.
I facing some design challenge :-
I have to instantiate a scoped bean after server start-up. It being a scoped bean doesn’t come up automatically.
It is subscriber class and needs to be instantiated as soon as the server starts and it has to be scoped for the processing further.
Thanks in advance.
Spring 3.0 has another scope called thread Scope
source: http://javarevisited.blogspot.sg/2012/05/what-is-bean-scope-in-spring-mvc.html
request – Return a single bean instance per HTTP request. *?
It’s like prototype.
not really, if the bean you use in the is inside a singleton, that prototype-instance will be always the same inside that singleton.
Many thanks MKyong for posting great tutorials.
typos here:
* what’s the diffreent between bean scopr singleton and prototype.
in singleton bean scope the container create a single instance(object) through the application but in case of prototype scope container create number of instance(object) as for the object creation call.
Thanks, article is updated.