Showing posts with label Spring Bean Scopes. Show all posts
Showing posts with label Spring Bean Scopes. Show all posts

Tuesday, 7 August 2018

Spring bean Prototype scope using annotation

Enjoying This Tutorial?

Subscribe to Ram N Java for high-quality, practical Java and Spring tutorials!

SUBSCRIBE NOW

Introduction

In the Spring Framework, bean scope determines the lifecycle and visibility of a bean instance managed by the IoC container. While the default scope is singleton (a single shared instance), configuring a bean as prototype instructs Spring to create a brand-new instance every time the bean is requested.

Why Use Prototype Scope?

  • Stateful Beans: Ideal for beans that maintain conversational or mutable state specific to a user or task.
  • Thread Safety: Because each caller gets its own instance, concurrent operations do not interfere with each other.
  • Annotation-Driven Simplicity: Instead of XML declarations, modern Spring uses annotations like @Scope("prototype") to keep configuration clean and intuitive.

Step-by-Step Configuration with Annotations

Configuring prototype scope is straightforward using the @Scope annotation alongside @Component or within a @Configuration class.

1. Using @Component with @Scope

package com.ram.model;

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

@Component
@Scope("prototype")
public class TaskService {
    public void execute() {
        System.out.println("Executing task in a new instance: " + this.hashCode());
    }
}

2. Verifying New Instances

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

TaskService task1 = context.getBean(TaskService.class);
TaskService task2 = context.getBean(TaskService.class);

// Returns false because each request produces a distinct object instance
System.out.println("Are beans identical? " + (task1 == task2));

Key Takeaway

Use prototype scope when your beans hold individual state that cannot be shared across multiple threads. Keep in mind that Spring initializes and configures prototype beans, but does not manage their complete lifecycle destruction—the client code is responsible for cleaning up prototype instances.


Click here to watch on Youtube:
https://www.youtube.com/watch?v=3M_70pTouhY&list=UUhwKlOVR041tngjerWxVccw

Click the below Image to Enlarge:
Spring bean Prototype scope using annotation

Spring bean Prototype scope using annotation
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%20http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ram.core</groupId>
    <artifactId>SpringDemo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringDemo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring 5 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>
</project>

Employee.java

package com.ram.model;

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

@Component
@Scope("prototype")
public class Employee
{
    private String name;

    public String getName()
    {
        return name;
    }

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

    @Override
    public String toString()
    {
        return "Employee [name=" + name + "]";
    }

}

applicationContext.xml

<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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd">


    <context:component-scan base-package="com.ram.model" />

</beans>

App.java

package com.ram.core;

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

import com.ram.model.Employee;

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

        System.out.println("-------------------------------------------");

        Employee employee1 = (Employee) context.getBean("employee");
        employee1.setName("John");

        System.out.println(
                "Got employee object from the ApplicationContext(Spring Container)");

        System.out.println(employee1);

        System.out.println("-------------------------------------------");
       
        Employee employee2 = (Employee) context.getBean("employee");
        System.out.println(
                "Got employee object from the ApplicationContext(Spring Container)");
        System.out.println(employee2);

    }

}

Output

Jul 25, 2018 10:59:22 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Wed Jul 25 10:59:22 IST 2018]; root of context hierarchy
Jul 25, 2018 10:59:22 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
-------------------------------------------
Got employee object from the ApplicationContext(Spring Container)
Employee [name=John]
-------------------------------------------
Got employee object from the ApplicationContext(Spring Container)
Employee [name=null]

Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_prototype_scope_annotation.zip?attredirects=0&d=1

Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_prototype_scope_annotation

Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/e1b6e4c3fbeda148bbe23a5cd92f521a01e39305/Spring_2018/SpringDemo_prototype_scope_annotation/?at=master

See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • Spring bean Singleton scope using annotation

    Enjoying This Tutorial?

    Subscribe to Ram N Java for high-quality, practical Java and Spring tutorials!

    SUBSCRIBE NOW

    Introduction

    In the Spring Framework, Singleton scope is the default lifecycle management behavior for all beans. When a bean is defined with singleton scope, the Spring IoC container creates exactly one shared instance of that bean per Spring container context. Every time the bean is requested or injected, Spring supplies that same shared cached instance.

    Why Use Singleton Scope?

    • Memory Efficiency: Only a single object instance is allocated in memory throughout the lifetime of the application context.
    • Stateless Services & Repositories: Perfect for service classes, DAO components, and utilities that do not store state specific to a particular user or thread.
    • Explicit Annotation Clarity: While singleton is default, explicitly annotating with @Scope("singleton") documents your design intent clearly for team members.

    Step-by-Step Configuration with Annotations

    You can declare a singleton bean cleanly by decorating your class with @Component (or @Service / @Repository) and @Scope("singleton"):

    1. Declaring the Singleton Bean

    package com.ram.service;
    
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    
    @Component
    @Scope("singleton")
    public class UserService {
        public void printStatus() {
            System.out.println("Executing from singleton instance: " + this.hashCode());
        }
    }

    2. Verifying Single Shared Instance

    ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    
    UserService service1 = context.getBean(UserService.class);
    UserService service2 = context.getBean(UserService.class);
    
    // Returns true because both references point to the exact same memory address
    System.out.println("Are beans identical? " + (service1 == service2));

    Key Takeaway

    Singleton beans should remain stateless or thread-safe because they are concurrently accessed across multiple application requests. If your bean requires mutable user state, consider switching to prototype scope or web-aware scopes.


    Click here to watch on Youtube:
    https://www.youtube.com/watch?v=9p-Kv84R1Bk&list=UUhwKlOVR041tngjerWxVccw

    Click the below Image to Enlarge:
    Spring bean Singleton scope using annotation

    Spring bean Singleton scope using annotation
    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%20http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.ram.core</groupId>
        <artifactId>SpringDemo</artifactId>
        <packaging>jar</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>SpringDemo</name>
        <url>http://maven.apache.org</url>

        <properties>
            <spring.version>5.0.2.RELEASE</spring.version>
        </properties>

        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>

            <!-- Spring 5 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>
    </project>

    Employee.java

    package com.ram.model;

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

    @Component
    @Scope("singleton")
    public class Employee
    {
        private String name;

        public String getName()
        {
            return name;
        }

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

        @Override
        public String toString()
        {
            return "Employee [name=" + name + "]";
        }

    }

    applicationContext.xml

    <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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd">


        <context:component-scan base-package="com.ram.model" />

    </beans>

    App.java

    package com.ram.core;

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

    import com.ram.model.Employee;

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

            System.out.println("-------------------------------------------");

            Employee employee1 = (Employee) context.getBean("employee");
            employee1.setName("John");

            System.out.println(
                    "Got employee object from the ApplicationContext(Spring Container)");

            System.out.println(employee1);

            System.out.println("-------------------------------------------");
           
            Employee employee2 = (Employee) context.getBean("employee");
            System.out.println(
                    "Got employee object from the ApplicationContext(Spring Container)");
            System.out.println(employee2);

        }

    }

    Output

    Jul 22, 2018 1:33:14 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Sun Jul 22 13:33:14 IST 2018]; root of context hierarchy
    Jul 22, 2018 1:33:14 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
    -------------------------------------------
    Got employee object from the ApplicationContext(Spring Container)
    Employee [name=John]
    -------------------------------------------
    Got employee object from the ApplicationContext(Spring Container)
    Employee [name=John]

    Click the below link to download the code:
    https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_singleton_scope_annotation.zip?attredirects=0&d=1

    Github Link:
    https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_singleton_scope_annotation

    Bitbucket Link:
    https://bitbucket.org/ramram43210/spring/src/e1b6e4c3fbeda148bbe23a5cd92f521a01e39305/Spring_2018/SpringDemo_singleton_scope_annotation/?at=master

    See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • Spring Prototype scope

    Enjoying This Tutorial?

    Subscribe to Ram N Java for high-quality, practical Java and Spring tutorials!

    SUBSCRIBE NOW

    Introduction

    In the Spring Framework, bean scope defines how the Spring IoC container creates, manages, and provides instances of beans. While Spring defaults to singleton scope (where one shared instance is reused), the prototype scope ensures that every single request for a bean produces a completely new, independent bean instance.

    The Core Essence of Prototype Scope

    • Fresh Instance Per Request: Every call to context.getBean() or every injection into another bean creates a brand-new object with its own state.
    • Ideal for Stateful Beans: When objects hold user-specific data, shopping carts, or transaction session data, prototype prevents state leakage across threads.
    • Lifecycle Responsibility: Spring creates, configures, and assembles prototype beans, but does not manage their full destruction lifecycle. The client code is responsible for cleaning up resources.

    Step-by-Step Configuration in Spring XML

    Setting up a prototype bean in XML is done simply by configuring the scope="prototype" attribute on the <bean> tag:

    1. Bean Definition in applicationContext.xml

    <bean id="customerService" 
          class="com.ram.service.CustomerService" 
          scope="prototype">
        <property name="message" value="Hello Prototype!" />
    </bean>

    2. Verifying Independent Instances in Java

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    CustomerService obj1 = (CustomerService) context.getBean("customerService");
    CustomerService obj2 = (CustomerService) context.getBean("customerService");
    
    // Output will be false: two distinct memory references
    System.out.println("Are beans identical? " + (obj1 == obj2));

    Key Takeaway

    Use prototype scope when your beans hold state that cannot be safely shared across concurrent execution threads. Remember that Spring hands over the prototype instance to the caller, meaning your code must handle any necessary resource disposal or cleanup.


    Click here to watch on Youtube:
    https://www.youtube.com/watch?v=GOGfxCp4ujs&list=UUhwKlOVR041tngjerWxVccw

    Click the below Image to Enlarge:
    Spring Prototype scope


    Spring Prototype scope

    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%20http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.ram.core</groupId>
        <artifactId>SpringDemo</artifactId>
        <packaging>jar</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>SpringDemo</name>
        <url>http://maven.apache.org</url>

        <properties>
            <spring.version>5.0.2.RELEASE</spring.version>
        </properties>

        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>

            <!-- Spring 5 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>
    </project>

    Employee.java

    package com.ram.model;

    public class Employee
    {
        private String name;

        public String getName()
        {
            return name;
        }

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

        @Override
        public String toString()
        {
            return "Employee [name=" + name + "]";
        }

    }

    applicationContext.xml

    <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-4.3.xsd">


        <bean id="employee" class="com.ram.model.Employee" scope="prototype">
        </bean>

    </beans>

    App.java

    package com.ram.core;

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

    import com.ram.model.Employee;

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

            System.out.println("-------------------------------------------");

            Employee employee1 = (Employee) context.getBean("employee");
            employee1.setName("John");

            System.out.println(
                    "Got employee object from the ApplicationContext(Spring Container)");

            System.out.println(employee1);

            System.out.println("-------------------------------------------");
           
            Employee employee2 = (Employee) context.getBean("employee");
            System.out.println(
                    "Got employee object from the ApplicationContext(Spring Container)");
            System.out.println(employee2);

        }

    }

    Output

    Jul 21, 2018 9:02:35 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Sat Jul 21 09:02:35 IST 2018]; root of context hierarchy
    Jul 21, 2018 9:02:35 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
    -------------------------------------------
    Got employee object from the ApplicationContext(Spring Container)
    Employee [name=John]
    -------------------------------------------
    Got employee object from the ApplicationContext(Spring Container)
    Employee [name=null]

    Click the below link to download the code:
    https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_prototype_scope.zip?attredirects=0&d=1

    Github Link:
    https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_prototype_scope

    Bitbucket Link:
    https://bitbucket.org/ramram43210/spring/src/e1b6e4c3fbeda148bbe23a5cd92f521a01e39305/Spring_2018/SpringDemo_prototype_scope/?at=master

    See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • Tutorials