Showing posts with label Singleton Scope. Show all posts
Showing posts with label Singleton Scope. Show all posts

Tuesday, 7 August 2018

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
  • Monday, 6 August 2018

    Spring Singleton 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 scopes define the lifecycle, visibility, and instantiation behavior of beans managed inside the Spring IoC container. The default and most fundamental scope is the Singleton scope. Understanding how the container creates, caches, and supplies singleton beans is essential for developing performant and reliable Spring applications.

    What Is Singleton Scope in Spring?

    • One Instance Per Container: Unlike the Gang of Four (GoF) singleton pattern (which enforces one instance per ClassLoader), Spring creates exactly one shared instance per ApplicationContext.
    • Shared and Cached: When the container starts, it creates the singleton instance and places it into an internal cache. Every subsequent lookup or injection returns that identical instance.
    • Default Behavior: If you omit the scope attribute in your XML bean definition, Spring automatically treats the bean as a singleton.

    Step-by-Step Configuration Example

    Here is how you configure and test a singleton bean using Spring XML configuration:

    1. Declaring the Bean in applicationContext.xml

    <!-- scope="singleton" can be explicitly set or omitted -->
    <bean id="welcomeService" 
          class="com.ram.service.WelcomeService" 
          scope="singleton">
        <property name="message" value="Welcome to Spring!" />
    </bean>

    2. Verifying Single Shared Reference in Java

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    WelcomeService service1 = (WelcomeService) context.getBean("welcomeService");
    WelcomeService service2 = (WelcomeService) context.getBean("welcomeService");
    
    // Both point to the exact same object reference
    System.out.println("Are beans identical? " + (service1 == service2)); // true
    System.out.println("Hash code 1: " + service1.hashCode());
    System.out.println("Hash code 2: " + service2.hashCode());

    Key Takeaway

    Singleton beans are best suited for stateless components such as service layers, repositories, and controllers. Because multiple threads concurrently access the single shared instance, avoid storing client-specific mutable state within singleton beans.


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

    Click the below Image to Enlarge:

    Spring Singleton scope

    Spring Singleton 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">
        </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 8:24:18 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Sat Jul 21 08:24:17 IST 2018]; root of context hierarchy
    Jul 21, 2018 8:24:18 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=John]

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

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

    Bitbucket Link:
    https://bitbucket.org/ramram43210/spring/src/764179f1702395ebc0d4ce50fe5125258c342eb8/Spring_2018/SpringDemo_singleton_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