Spring bean scopes

The scope of a bean specifies what kind of object has to be created by container for the bean defined.

We can define the scope of the bean while defining the bean in the spring configuration file.

Spring provides 5 scopes for a bean out of the box, we can also customize and create custom scope.

5 types of bean scopes supported by Spring out of the box are as below

1.singleton – Return a single bean instance per Spring container

2.prototype – Return a new bean instance each time when requested for the container

3.request – Return a single bean instance per HTTP request and Only valid in the context of a web-aware Spring ApplicationContext which means only in the web application.

4.session – Return a single bean instance per HTTP session and Only valid in the context of a web-aware Spring ApplicationContext which means only in the web application.

5.globalSession – Return a single bean instance per global HTTP session
In portlet applications, session scope is considered as global session scope.
hence only valid when used in a portlet context

Note: By default, all the beans defined in spring will have singleton scope.

Let us see Singleton bean with example

Create a class called Person as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kb.beans.scope;
 
public class Person {
    
    private String name;
    
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
}
package com.kb.beans.scope;

public class Person {
	
	private String name;
	

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

Define the Person bean in the spring configuration file

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    
    <bean id="person"  class="com.kb.beans.scope.Person">
    <property name="name" value="Name1"/>
    </bean>
</beans>
<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
  		http://www.springframework.org/schema/context/spring-context-3.2.xsd">
	
	<bean id="person"  class="com.kb.beans.scope.Person">
	<property name="name" value="Name1"/>
	</bean>
</beans>

Note that,we have not defined any scope for the bean person in the above file

But spring automatically adds the default scope singleton

As explained above, singleton bean will be only one instance for entire spring container, no matter how many times and in how many places we access it using context.getBean() method.

Create pom.xml as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>Spring</groupId>
  <artifactId>SpringCore</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>SpringCore</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>
  
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>Spring</groupId>
  <artifactId>SpringCore</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SpringCore</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  <dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>
  <dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>
  
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Let us test the same in the below class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.kb.beans.scope;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class BeanScopeTest {
    
    public static void main(String[] args) {
        
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
 
        // Load Person object
        Person person1 = (Person) applicationContext.getBean("person");
        System.out.println("Name : " + person1.getName());
        
        Person person2 = (Person) applicationContext.getBean("person");
 
System.out.println(person1 == person2);
 
        applicationContext.registerShutdownHook();
 
    }
}
package com.kb.beans.scope;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopeTest {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

		// Load Person object
		Person person1 = (Person) applicationContext.getBean("person");
		System.out.println("Name : " + person1.getName());
		
		Person person2 = (Person) applicationContext.getBean("person");

System.out.println(person1 == person2);

		applicationContext.registerShutdownHook();

	}
}

Run the above class and see the output

Even though we have accessed the bean 2 times using getBean() method. We can see that 2 instances are same.

When we compare 2 instances using == , it always checks the memory location of the 2 objects, and it is returning true which means both are same objects.

Now let’s modify the above program as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.kb.beans.scope;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class BeanScopeTest {
    
    public static void main(String[] args) {
        
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
 
        // Load Person object
        Person person1 = (Person) applicationContext.getBean("person");
        
        person1.setName("Name2");
        
        System.out.println("Name : " + person1.getName());
        
        Person person2 = (Person) applicationContext.getBean("person");
        
        System.out.println("Name : " + person2.getName());
        
        System.out.println(person1 == person2);
 
        applicationContext.registerShutdownHook();
 
    
    }
 
}
package com.kb.beans.scope;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopeTest {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

		// Load Person object
		Person person1 = (Person) applicationContext.getBean("person");
		
		person1.setName("Name2");
		
		System.out.println("Name : " + person1.getName());
		
		Person person2 = (Person) applicationContext.getBean("person");
		
		System.out.println("Name : " + person2.getName());
		
		System.out.println(person1 == person2);

		applicationContext.registerShutdownHook();

	
	}

}

Here we have modified the person1 object to have a new name Name2
And loading person2 then accessing its name.

Now person2 also has a new name Name2 even though we have modified only person1

It clearly says that, both are one and the same instance.

Prototype scope of a bean

What is prototype scope in spring ?

Prototype scope means container creates new instance every time we ask container to provide the bean using getBean() method.

In simple words, each context.getBean() method returns a new object.

Lets see the example for the same

Create a class called User as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.kb.beans.scope;
 
public class User {
    private String name;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
}
package com.kb.beans.scope;

public class User {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

Define the bean and make it as prototype explicitly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    
    <bean id="person"  class="com.kb.beans.scope.Person">
    <property name="name" value="Name1"/>
    </bean>
    
    <bean id="user"  class="com.kb.beans.scope.User" scope="prototype">
    <property name="name" value="Name1"/>
    </bean>
    
</beans>
<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
  		http://www.springframework.org/schema/context/spring-context-3.2.xsd">
	
	<bean id="person"  class="com.kb.beans.scope.Person">
	<property name="name" value="Name1"/>
	</bean>
	
	<bean id="user"  class="com.kb.beans.scope.User" scope="prototype">
	<property name="name" value="Name1"/>
	</bean>
	
</beans>

Now try to access the bean customer from the test class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.kb.beans.scope;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class BeanScopeTest {
    
    public static void main(String[] args) {
        
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
 
        
        // prototype
        
        User user1 = (User) applicationContext.getBean("user");
        
        user1.setName("Name2");
        
        System.out.println("Name : " + user1.getName());
        
        
        
        User user2 = (User) applicationContext.getBean("user");
        
        System.out.println("Name : " + user2.getName());
        
        System.out.println(user1 == user2);
 
        applicationContext.registerShutdownHook();
 
    
    }
 
}
package com.kb.beans.scope;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopeTest {
	
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

		
		// prototype
		
		User user1 = (User) applicationContext.getBean("user");
		
		user1.setName("Name2");
		
		System.out.println("Name : " + user1.getName());
		
		
		
		User user2 = (User) applicationContext.getBean("user");
		
		System.out.println("Name : " + user2.getName());
		
		System.out.println(user1 == user2);

		applicationContext.registerShutdownHook();

	
	}

}

Run the above program and see the output

Here we got the bean user1 by calling getBean() method

We changed its name to Name2 and then we accessed the bean user2 by calling getBean() method and its name is printed.

Note that, user2 has no affect of new Name this is because , the scope of User bean is set to prototype.

Also we compared user1 and user2 using == and it displayed as false, which means both are different objects.

So prototype scope always ensures that, each getBean() invocation returns the new object.

Prototype scope must be defined explicitly

Download this project BeanScopes.zip

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on