Spring Bean Scopes
March 12, 2023
This page will walk through Spring bean scope example using @Scope
annotation and XML configuration. Using scoped proxy, we will understand how to inject short lived bean scope to long lived bean scope. The Scopes provided by Spring are singleton, prototype, request, session, globalSession and application. The singleton and prototype scopes are Spring's standard scope and can be used in standalone as well as web application. The other bean scope that are request, session, globalSession and application are valid only in web aware application. globalSession scope is specific to portlet application. Here on this page, we will use XML configuration as well as @Scope
annotation to provide the examples of Spring bean scopes.
Contents
- 1. Spring Bean Scopes
- 2. Prototype Scope using XML
- 3. Singleton Scope using XML
- 4. Prototype Scope using @Scope Annotation
- 5. Singleton Scope using @Scope Annotation
- 6. Scoped Proxy : Scoped Beans as Dependencies
- 7. Request Scope using XML
- 8. Session Scope using XML
- 9. Global Session Scope using XML
- 10. Application Scope using XML
- 11. Request Scope using @Scope Annotation
- 12. Session Scope using @Scope Annotation
- 13. Global Session Scope using @Scope Annotation
- 14. Application Scope using @Scope Annotation
- 15. Reference
- 16. Download Complete Source Code
1. Spring Bean Scopes
As of Spring 4.2 release, there are following bean scopes.1. singleton
2. prototype
3. request
4. session
5. globalSession
6. application
1.1 singleton Scope
singleton
scope is default scope of a bean in spring container. In this scope, spring creates only one instance of the bean and it is served for every request for that bean from cache within the container. Only one instance of bean per bean id is created in singleton scope. If two beans with different id but of same class is there in singleton scope, then two instances will be created of that class and in terms of bean id, only one instance of bean is created. In singleton
scope, one instance of bean is created by spring container and put in cache. In spring bean dependency, singleton
scoped bean is injected from cache as shared bean. singleton
scope is limited to spring container. This differs from the Java Singleton Design Pattern which is based on per ClassLoader. In spring, singleton is per container and per bean. singleton
scope is standard scope in spring and is valid in standalone as well as web applications. singleton
scope is used for stateless beans.
1.2 prototype Scope
In springprototype
scope, spring container creates new instance of bean for each and every request for that bean. In spring bean dependency, prototype
scoped bean is served by creating new instance of bean for each and every bean dependency. prototype
scope is used for stateful beans. Spring container does not maintain the full record of prototype
scoped beans. After instantiating bean and submitting it to client, spring container does not maintain the record. So to release the resources held by prototype
scoped bean, client should implement custom bean post-processor. prototype
scope is spring standard scope and can be used in standalone as well as web application of spring.
1.3 request Scope
In spring,request
scoped bean is used in HTTP request life-cycle. For each and every HTTP request, new instance of bean is created and is alive for complete HTTP request life-cycle. request
scoped bean cannot be used with spring standalone application, it can be used only in web application. In one HTTP request, only one instance of request
scoped bean is created and in other subsequent request another instance of bean is created per request. The life cycle of request
scoped bean starts and ends within the life cycle of HTTP request. Within HTTP request, the changes done in request
scoped bean does not affect the other HTTP request. Once HTTP request is completed, the instance of request
scoped bean is also destroyed. We can understand request
scoped bean as per HTTP request and per bean id.
1.4 session Scope
session
scoped bean in spring is used in HTTP Session of web application. For each and every HTTP session, only one instance of bean is created and is alive for complete HTTP session life cycle. The life cycle of session
scoped bean is within the life cycle of HTTP session life cycle. If HTTP session is discarded, the session
scoped bean created within HTTP session is also discarded. Two parallel HTTP sessions do not share the changes done in session
scoped bean instances. Once the HTTP session is out, the session
scoped bean instance is also destroyed created within that HTTP session. session
scoped bean is per HTTP session and per bean id.
1.5 globalSession Scope
globalSession
scoped bean is used in portlet based spring web application. Only one instance of globalSession
scoped bean is created for life cycle of global HTTP session. Global HTTP session is the HTTP session that is shared among all portlets to make a single portlet web application. globalSession
scoped bean instance has the life cycle within global HTTP session life cycle. The changes done in globalSession
scoped bean instance does not affect to another parallel global HTTP session. Once the global HTTP session is out, the instance of globalSession
scoped bean is also destroyed. globalSession
scoped bean is per global HTTP session and per bean id.
1.6 application Scope
application
scope has been introduced in Spring 4.0. Only one instance of bean is created for the complete life cycle of ServletContext
. The instance of application
scoped bean is stored as ServletContext
attribute. application
scoped bean is used in spring web application. This scope is similar to singleton
scope with one difference that application
scope is ServletContext
specific and singleton
scope is spring ApplicationContext
specific.
2. Prototype Scope using XML
To understand prototype scope, find the code snippet. In spring<bean>
tag, there is an attribute as scope
which assigns the scope value as prototype
.
<bean id="address" class="com.concretepage.bean.Address" scope="prototype"> <constructor-arg name="city" value="Varanasi"/> </bean>
spring-config.xml
<?xml version="1.0" encoding="UTF-8"?> <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.xsd"> <bean id="address" class="com.concretepage.bean.Address" scope="prototype"> <constructor-arg name="city" value="Varanasi"/> </bean> <bean id="teacher" class="com.concretepage.bean.Teacher"> <property name="teachAddress" ref="address"/> </bean> <bean id="student" class="com.concretepage.bean.Student"> <property name="stAddress" ref="address"/> </bean> </beans>
package com.concretepage.bean; public class Address { private String city; public Address(String city) { this.city = city; System.out.println("My city:" + city); } public String getCity() { return city; } }
package com.concretepage.bean; public class Student { private Address stAddress; public Address getStAddress() { return stAddress; } public void setStAddress(Address stAddress) { this.stAddress = stAddress; } }
package com.concretepage.bean; public class Teacher { private Address teachAddress; public Address getTeachAddress() { return teachAddress; } public void setTeachAddress(Address teachAddress) { this.teachAddress = teachAddress; } }
package com.concretepage; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringDemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); } }
apply plugin: 'java' apply plugin: 'eclipse' archivesBaseName = 'SpringDemo' version = '1' repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter:1.2.7.RELEASE' }
My city:Varanasi My city:Varanasi
3. Singleton Scope using XML
In singleton bean scope, we need to assignsingleton
value to the attribute scope
.
<bean id="address" class="com.concretepage.bean.Address" scope="singleton"> <constructor-arg name="city" value="Varanasi"/> </bean>
spring-config.xml
and then run the code. In the output we will observe that the bean scoped as singleton has been instantiated only one time. Find the output.
My city:Varanasi
4. Prototype Scope using @Scope Annotation
Spring provides@Scope
annotation to keep the bean in desired scope. Just annotate the class with this annotation and provide the bean scope value. Find the code snippet for how to use @Scope
annotation with prototype
scope.
@Scope("prototype") public class Address {}
Address.java
package com.concretepage.bean; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Scope("prototype") @Component public class Address { private String city = "Varanasi"; public Address() { System.out.println("My city:" + city); } public String getCity() { return city; } }
Student.java
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Student { @Autowired private Address stAddress; public Address getStAddress() { return stAddress; } }
Teacher.java
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Teacher { @Autowired private Address teachAddress; public Address getTeachAddress() { return teachAddress; } }
AppConfig.java
package com.concretepage; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages="com.concretepage.bean") public class AppConfig { }
SpringDemo.java
package com.concretepage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class SpringDemo { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); } }
5. Singleton Scope using @Scope Annotation
To use singleton scope with@Scope
annotation, we need to do changes as below. Just change the scope value as singleton
.
@Scope("singleton") public class Address {}
6. Scoped Proxy : Scoped Beans as Dependencies
In the case when we inject short lived bean (like request, session scope) in long lived bean (like singleton and prototype) then we need to use AOP proxy in place of scoped bean. It means we need to inject proxy object.1. In case of XML, we can use spring tag
<aop:scoped-proxy/>
for short lived scope bean.
2. In case of
@Scope
annotation, spring provides attribute as proxyMode
which has the values as TARGET_CLASS, NO, INTERFACES and DEFAULT.
7. Request Scope using XML
Find the code snippet for how to use request scope using XML.<bean id="address" class="com.concretepage.bean.Address" scope="request"> <constructor-arg name="city" value="Varanasi"/> <aop:scoped-proxy/> </bean>
<;aop:scoped-proxy/>;
tag when we are injecting our short lived bean to long lived bean. In our example, we are injecting request scoped bean to singleton scoped bean.
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <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" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd""> <mvc:annotation-driven /> <context:component-scan base-package="com.concretepage.controller" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="address" class="com.concretepage.bean.Address" scope="request"> <constructor-arg name="city" value="Varanasi"/> <aop:scoped-proxy/> </bean> <bean id="teacher" class="com.concretepage.bean.Teacher"> <property name="teachAddress" ref="address"/> </bean> </beans>
package com.concretepage.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.concretepage.bean.Teacher; @Controller @RequestMapping("/hello") public class HelloController { @Autowired private Teacher teacher; @RequestMapping public ModelAndView hello(ModelAndView modelAndView) { modelAndView.setViewName("hello"); modelAndView.addObject("city", teacher.getTeachAddress().getCity()); return modelAndView; } }
<?xml version="1.0" encoding="ISO-8859-1" ?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd" version="3.0"> <display-name>Spring MVC Application</display-name> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
<html> <head><title>Hello Spring Scopes</title></head> <body> My City: ${city} </body> </html>
build.gradle
dependencies { compile 'org.springframework.boot:spring-boot-starter-web:1.2.7.RELEASE' compile 'jstl:jstl:1.2' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.2.7.RELEASE' }
My city:Varanasi
8. Session Scope using XML
To use session scope using XML, just change the scope value assession
.
<bean id="address" class="com.concretepage.bean.Address" scope="session"> <constructor-arg name="city" value="Varanasi"/> <aop:scoped-proxy/> </bean>
9. Global Session Scope using XML
To use global session scope using XML, just change the scope value as globalSession
.
<bean id="address" class="com.concretepage.bean.Address" scope="globalSession"> <constructor-arg name="city" value="Varanasi"/> <aop:scoped-proxy/> </bean>
10. Application Scope using XML
To use application scope using XML, just change the scope value as application
.
<bean id="address" class="com.concretepage.bean.Address" scope="application"> <constructor-arg name="city" value="Varanasi"/> <aop:scoped-proxy/> </bean>
11. Request Scope using @Scope Annotation
To use request scope using@Scope
annotation, we can do as follows.
@Scope(value="request", proxyMode =ScopedProxyMode.TARGET_CLASS) public class Address {}
@Scope
annotation has the attribute proxyMode
that is used to create AOP proxy of the bean. We need to do it when we are injecting short lived bean scope to long lived bean scope. In our example, we are injecting request scope bean to singleton scope bean.
Find the code.
Address.java
package com.concretepage.bean; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; @Scope(value="session", proxyMode =ScopedProxyMode.TARGET_CLASS) @Component public class Address { private String city = "Varanasi"; public Address() { System.out.println("My city:" + city); } public String getCity() { return city; } }
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Teacher { @Autowired private Address teachAddress; public Address getTeachAddress() { return teachAddress; } }
package com.concretepage; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @ComponentScan(basePackages="com.concretepage") @EnableWebMvc public class AppConfig { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/pages/"); resolver.setSuffix(".jsp"); return resolver; } }
package com.concretepage; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class WebAppInitializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(AppConfig.class); ctx.setServletContext(servletContext); Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); dynamic.addMapping("/"); dynamic.setLoadOnStartup(1); } }
12. Session Scope using @Scope Annotation
To use session scope using@Scope
annotation, use the value as session
.
@Scope(value="session", proxyMode =ScopedProxyMode.TARGET_CLASS) public class Address {}
13. Global Session Scope using @Scope Annotation
To use global session scope using@Scope
annotation, use the value as globalSession
.
@Scope(value="globalSession", proxyMode =ScopedProxyMode.TARGET_CLASS) public class Address {}
14. Application Scope using @Scope Annotation
To use application scope using@Scope
annotation, use the value as application
.
@Scope(value="application", proxyMode =ScopedProxyMode.TARGET_CLASS) public class Address {}