Spring Bean Scopes

The Primary Spring bean scopes are Singleton and Prototype. In Singleton scope, the spring container instantiates only one instance of a bean per container. In Prototype scope, the container returns a new instance of a bean whenever we ask the container for that bean. Other bean scopes applicable only to web environments are request, session, application and websocket. In this tutorial, we will only look at singleton and prototype scopes.

What is the default Spring Bean Scope

The default Spring Bean scope is singleton. i.e. if you do not specify a scope for the bean then spring assumes that its singleton.

Example of Spring Bean Scopes

Imagine a Ticket Vending Machine that is usually available in underground metro railway stations. There is generally only one instance of the vending machine and in a spring context, we would create a singleton for the vending machine. However, a Ticket Vending Machine generates a new instance on Ticket every time. In this case, ticket bean has scope Prototype.

In the sample program, we define two classes: TicketVendingMachine and Ticket. We shall declare TicketVendingMachine as Singleton and Ticket as Prototype. We shall fetch two references of TicketVendingMachine from Spring and verify that both the references point to the same instance of TicketVendingMachine because TicketVendingMachine bean is defined as Singleton. Then we shall fetch two references of Ticket from Spring and verify that both the references point to the different instances of Ticket because Ticket bean is defined as Prototype.

Create TicketVendingMachine class

package com.studytrails.springbeanscopes;
public class TicketVendingMachine {
}

Create Ticket class

package com.studytrails.springbeanscopes;
public class Ticket {
}

Declare the TicketVendingMachine and Ticket classes in spring-config.xml (see line 10 and line 14 below).
TicketVendingMachine is declared explicitly with scope Singleton. This is the default scope of all beans in Spring. i.e. even if scope=”Singleton” is not mentioned explicitly, still, the TicketVendingMachine bean will have the scope as Singleton by default. Ticket is declared with scope Prototype

Finally, we need a java program to test the Singleton and Prototype setup.This is done by TestSingletonAndPrototype.java (see source code below). We need to tell Spring framework to use the ‘spring-config.xml’ to load our beans(see line 11 below). There are two references of TicketVendingMachine bean and we compare the two instances and print the result of the comparison. The result of this comparison should return true indicating the two references point to the same instance because TicketVendingMachine is declared as Singleton. We get two references of Ticket bean . We then compare the two instances and print the result of the comparison. The result of this comparison should return false indicating that the two references point to different instances because Ticket is declared as Prototype.

package com.studytrails.SpringBeanScopes;

package com.studytrails.springbeanscopes;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopesTest {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		TicketVendingMachine ticketVendingMachine1 = (TicketVendingMachine) context.getBean("ticketVendingMachine");
		TicketVendingMachine ticketVendingMachine2 = (TicketVendingMachine) context.getBean("ticketVendingMachine");
		boolean areTicketVendingMachineInstancesSame = ticketVendingMachine1.equals(ticketVendingMachine2);
		System.out.println(areTicketVendingMachineInstancesSame); // print true
		Ticket ticket1 = (Ticket) context.getBean("ticket");
		Ticket ticket2 = (Ticket) context.getBean("ticket");
		boolean areTicketInstancesSame = ticket1.equals(ticket2);
		System.out.println(areTicketInstancesSame); // prints false
	}
}

Spring Bean scope annotation

It is also possible to declare the spring bean scope using annotations. The AnnotationConfigApplicationContext class reads a Java config file that defines the bean. The methods annotated with @Bean define the bean and the same methods use the @Scope annotation to define the scope. We use the same example as above but this time we use annotations.

Example of Spring bean scope annotation

Here’s the Config class annotated with @configuration, @Bean and @Scope.

package com.studytrails.springbeanscopes.annotated;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class AppConfig {

	@Bean
	@Scope(scopeName = "singleton")
	public Ticket getTicket() {
		return new Ticket();
	}

	@Bean
	@Scope(scopeName = "prototype")
	public TicketVendingMachine getTicketVendingMachine() {
		return new TicketVendingMachine();
	}

}

The definition of Ticket and TicketVendingMachine are same as above. Here’s the main method

package com.studytrails.springbeanscopes.annotated;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.studytrails.springbeanscopes.Ticket;
import com.studytrails.springbeanscopes.TicketVendingMachine;

public class AnnotatedBeanScopeTest {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		TicketVendingMachine ticketVendingMachine1 = (TicketVendingMachine) context.getBean("ticketVendingMachine");
		TicketVendingMachine ticketVendingMachine2 = (TicketVendingMachine) context.getBean("ticketVendingMachine");
		boolean areTicketVendingMachineInstancesSame = ticketVendingMachine1.equals(ticketVendingMachine2);
		System.out.println(areTicketVendingMachineInstancesSame); // print true
		Ticket ticket1 = (Ticket) context.getBean("ticket");
		Ticket ticket2 = (Ticket) context.getBean("ticket");
		boolean areTicketInstancesSame = ticket1.equals(ticket2);
		System.out.println(areTicketInstancesSame); // prints false
	}
}

Spring Bean scope features

  • Use the prototype bean when the bean carries a state i.e. its stateful. Use singleton bean for stateless beans.
  • For a prototype bean, the container does not manage the complete lifecyle of the bean. It initiates, configures and assembles a prototype bean and then hands it over to the client. The destruction lifecycle methods are not called.
  • The dependencies of a bean are resolved at instantiation time, therefore if a singleton bean needs a prototype bean, the container creates one during instantiation of the singleton bean. The singleton bean would therefore always have the same instance of prototype bean.

That finishes our tutorial on the Singleton and prototype bean. We look at the web scopes in a later tutorial.

2 thoughts on “Spring Bean Scopes”

Leave a Comment