How do I define bean scoping in Spring?

Bean scoping is how the bean is created and returned from the spring container to the bean requester. By default, the scope of all bean is singleton. The spring container will always return the same bean whenever this bean is required, for instance when in injected or call using the getBean() method from the application context.

There are five types of bean scope define in the Spring Container:

Scope Description
singleton Scope the bean definition to a single bean instance per Spring Container. This is the default scope when no scope is defined when creating a bean.
prototype Scope the bean to allow multiple times bean creation. This will create a new bean for each time the bean is required.
request Scope the bean definition to a single HTTP request. *
session Scope the bean definition to a single HTTP session. *
global-session Scope the bean definition to a global HTTP session. *

*) This is only valid when using the web-capable Spring context.

Let’s see the difference between Singleton and Prototype scope. First we’ll create our DummyService class.

package org.kodejava.spring.core;

public class DummyService {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Singleton Scope

By default, when no scope defined it will be a singleton.

<?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="service" class="org.kodejava.spring.core.DummyService" />

</beans>

Now create a program to run our example. First will run it using the singleton.xml as the configuration.

package org.kodejava.spring.core;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopeDemo {
    public static void main(String[] args) {
        try (var context = new ClassPathXmlApplicationContext("singleton.xml")) {
            DummyService serviceA = (DummyService) context.getBean("service");
            serviceA.setMessage("Hello From A");
            System.out.println("Message A = " + serviceA.getMessage());

            DummyService serviceB = (DummyService) context.getBean("service");
            System.out.println("Message B = " + serviceB.getMessage());
        }
    }
}

The output of the singleton configuration is:

Message A = Hello From A
Message B = Hello From A

The above output show that the message printed by the serviceB is the same as the serviceA. We don’t even set the message in the serviceB explicitly. It prints the same message because the getBean() method actually return the same bean both for serviceA and serviceB. This is the singleton scope.

Prototype Scope

To change the scope to prototype use the scope attribute in the bean element as shown below.

<?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="service" class="org.kodejava.spring.core.DummyService" scope="prototype" />

</beans>
package org.kodejava.spring.core;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopePrototypeDemo {
    public static void main(String[] args) {
        try (var context = new ClassPathXmlApplicationContext("prototype.xml")) {
            DummyService serviceA = (DummyService) context.getBean("service");
            serviceA.setMessage("Hello From A");
            System.out.println("Message A = " + serviceA.getMessage());

            DummyService serviceB = (DummyService) context.getBean("service");
            System.out.println("Message B = " + serviceB.getMessage());
        }
    }
}

Now if you try to run the same program again but changing the configuration to prototype.xml you’ll get the following output printed:

Message A = Hello From A
Message B = null

The serviceB now print a different message. This is the effect of using the prototype scope. When we call the getBean() a new bean will be created per request.

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I share object or data between users in web application?

In a web application there are different type of scope where we can store object or data. There are a page, request, session and application scope.

To share data between users of the web application we can put a shared object in application scope which can be done by calling setAttribute() method of the ServletContext. By this way data can then be accessing by other users by calling the getAttribute() method of the ServletContext.

Let’s see the example code in a simple servlet.

package org.kodejava.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "SharedObjectServlet", urlPatterns = "/shared-object")
public class ApplicationContextScopeAttribute extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        ServletContext context = this.getServletContext();
        context.setAttribute("HELLO.WORLD", "Hello World 123");
    }
}

And here is what we code in the JSP page to access it.

<%= request.getServletContext().getAttribute("HELLO.WORLD") %>

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central