Beans

Spring Bean Scopes Example

In this example we are going to demonstrate the types of Bean scopes provided by Spring 3.2.3. In Spring a Bean definition is a recipe for creating actual instances of the class defined. The scope of the objects created by a bean definition can be chosen through configuration. The Spring Framework provides five scopes, that are described below:

  • singleton : scopes to a single object instance per Spring IOC Container.
  • prototype : scopes to any number of object instances
  • request : scopes to the lifecycle of a single HTTP request, available only when using a web aware ApplicationContext.
  • session : scopes to the lifecycle of an HTTP session, also available only when using a web aware ApplicationContext.
  • global session : scopes to the lifecycle of a global HTTP session, also available only when using a web aware ApplicationContext.

Here, we shall show the differences between a singleton scoped bean and a prototype scoped bean. We shall also provide an annotation-based solution to define a bean scope.

Our preferred development environment is Eclipse. We are using Eclipse Juno (4.2) version, along with Maven Integration plugin version 3.1.0. You can download Eclipse from here and Maven Plugin for Eclipse from here. The installation of Maven plugin for Eclipse is out of the scope of this tutorial and will not be discussed. We are also using Spring version 3.2.3 and the JDK 7_u_21.

Let’s begin.

1. Create a new Maven project

Go to File -> Project ->Maven -> Maven Project.

New-Maven-Project

In the “Select project name and location” page of the wizard, make sure that “Create a simple project (skip archetype selection)” option is checked, hit “Next” to continue with default values.

Maven-Project-Name-Location

In the “Enter an artifact id” page of the wizard, you can define the name and main package of your project. We will set the “Group Id” variable to "com.javacodegeeks.snippets.enterprise" and the “Artifact Id” variable to "springexample". The aforementioned selections compose the main project package as "com.javacodegeeks.snippets.enterprise.springexample" and the project name as "springexample". Hit “Finish” to exit the wizard and to create your project.

Configure-Maven-Project

The Maven project structure is shown below:

Maven-project-structure

    It consists of the following folders:

  • /src/main/java folder, that contains source files for the dynamic content of the application,
  • /src/test/java folder contains all source files for unit tests,
  • /src/main/resources folder contains configurations files,
  • /target folder contains the compiled and packaged deliverables,
  • the pom.xml is the project object model (POM) file. The single file that contains all project related configuration.

2. Add Spring 3.2.3 dependency

  • Locate the “Properties” section at the “Overview” page of the POM editor and perform the following changes:
    Create a new property with name org.springframework.version and value 3.2.3.RELEASE.
  • Navigate to the “Dependencies” page of the POM editor and create the following dependencies (you should fill the “GroupId”, “Artifact Id” and “Version” fields of the “Dependency Details” section at that page):
    Group Id : org.springframework Artifact Id : spring-web Version : ${org.springframework.version}

Alternatively, you can add the Spring dependencies in Maven’s pom.xml file, by directly editing it at the “Pom.xml” page of the POM editor, as shown below:
 
pom.xml:

<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>com.javacodegeeks.snippets.enterprise</groupId>
	<artifactId>springexample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<properties>
		<spring.version>3.2.3.RELEASE</spring.version>
	</properties>
</project>

As you can see Maven manages library dependencies declaratively. A local repository is created (by default under {user_home}/.m2 folder) and all required libraries are downloaded and placed there from public repositories. Furthermore intra – library dependencies are automatically resolved and manipulated.

3. Singleton scope vs Prototype scope

In order to show the differences between a singleton bean and a prototype bean, we create a single Spring bean, HelloWorld and use different scope configuration to see the differences in its behaviour.
 
HelloWorld.java:

package com.javacodegeeks.snippets.enterprise.services;

public class HelloWorld {
	
	private String name;

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

	public String toString(){
		return "HelloWorld! \n" + name;
	}

}

3.1. Bean scoped as a singleton

When we define the bean and it is scoped as a singleton, the Spring IOC Container will only create exactly one instance of the object defined by that bean definition. All requests for beans with id matching that bean definition will result in that one specific bean instance returned from the Spring Container.
 
applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 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 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
	
	<bean id="helloWorldBean" class="com.javacodegeeks.snippets.enterprise.services.HelloWorld" scope="singleton">
	</bean>

	</beans>

If no scope is defined for the bean, the default scope is singleton.

3.2 Bean scoped as a prototype

When we define the bean with prototype scope, then every time a request for that bean is made, a new instance of the object defined by that bean definition is created.
 
applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 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 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
	
	<bean id="helloWorldBean" class="com.javacodegeeks.snippets.enterprise.services.HelloWorld" scope="prototype">
	</bean>

	</beans>

3.3 Run the application

In the App.class we load the helloWorldBean through the ApplicationContext . We retrieve the bean in two different objects.
 
App.java:

package com.javacodegeeks.snippets.enterprise;

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

import com.javacodegeeks.snippets.enterprise.services.HelloWorld;

public class App {
	
	@SuppressWarnings("resource")
	public static void main(String[] args) {
	
			ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

			HelloWorld helloObj1 = (HelloWorld) context.getBean("helloWorldBean");

			helloObj1.setName("name set by object 1");

			System.out.println(helloObj1);

			HelloWorld helloObj2 = (HelloWorld) context.getBean("helloWorldBean");

			System.out.println(helloObj2);
	}
}

3.4 Output

When we execute the application, using the singleton scoped bean, both objects have the same values, since they use the same instance of the bean.

HelloWorld! 
name set by object 1
HelloWorld! 
name set by object 1

 
When we execute the application, using the prototyped scoped bean, the two objects have different instances of the bean. The second object has not set a value to its field, so it is null.

HelloWorld! 
name set by object 1
HelloWorld! 
null

 

4. Annotation-based bean scopes

An easy way to define the bean scope is by using annotations. The HelloWorld bean can be defined without the use of XML configuration, as shown below:
 
HelloWorld.java:

package com.javacodegeeks.snippets.enterprise.services;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service("helloWorldBean")
@Scope("prototype")
public class HelloWorld {
	
	private String name;

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

	public String toString(){
		return "HelloWorld! \n" + name;
	}

}

The @Service annotation is used to define the Spring bean, whereas the @Scope annotation defines the scope of the bean. Now the XML configuration is limited to only enabling the auto component scanning.
 
applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 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 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
	
	<context:component-scan base-package="" />

	</beans>

The App.class loads the annotation-based bean as shown below:
 
HelloWorld.java:

package com.javacodegeeks.snippets.enterprise;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.javacodegeeks.snippets.enterprise.services.HelloWorld;

public class App {
	
	@SuppressWarnings("resource")
	public static void main(String[] args) {
	
			ApplicationContext context = new AnnotationConfigApplicationContext(HelloWorld.class);
			HelloWorld helloObj1 = (HelloWorld) context.getBean("helloWorldBean");
			helloObj1.setName("name set by object 1");
			System.out.println(helloObj1);
			HelloWorld helloObj2 = (HelloWorld) context.getBean("helloWorldBean");
			System.out.println(helloObj2);
	}
}

 
This was an example of the Bean scopes provided by Spring 3.2.3.
Download the Eclipse project of this part : springBeanScope.zip

Theodora Fragkouli

Theodora has graduated from Computer Engineering and Informatics Department in the University of Patras. She also holds a Master degree in Economics from the National and Technical University of Athens. During her studies she has been involved with a large number of projects ranging from programming and software engineering to telecommunications, hardware design and analysis. She works as a junior Software Engineer in the telecommunications sector where she is mainly involved with projects based on Java and Big Data technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button