Spring @Scope annotation with Singleton Scope Example

In this article, we will discuss how to create a bean scoped as a singleton using the @Scope annotation.

We use @Scope to define the scope of a @Component class or a @Bean definition.

When a Spring bean is scoped as a singleton, the Spring IoC container creates exactly one instance of the object defined by that bean definition.
 
By default, the Spring IoC container creates and initializes all beans as singletons. However, we can define a bean's scope as a singleton using the scope="singleton" attribute of the element or the @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) annotation.

YouTube Video - Spring @Scope Annotation

 We will demonstrate this example using Annotation based (@Component) as well as Java-based configuration(@Bean). 

Spring @Scope Annotation + Singleton Scope + @Component Example

Let's create an example to demonstrate the use of @Scope annotation with a singleton scope in a spring application. 

Create a Simple Maven Project

Create a simple Maven project using your favourite IDE. Refer to the section below for the packaging structure. If you are new to Maven, read this article: How to Create a Simple Maven Project.

Project Structure

The below diagram shows a project structure for your reference - 

The pom.xml File

Note that Spring Framework 6 required Java 17 or later version:
<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
    <artifactId>learn-spring-framework</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>6.0.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.4</version>
        </dependency>

    </dependencies>
</project>

MessageService.java

Next, let's create a MessageService interface as follows.
package net.javaguides.spring.scope;

public interface MessageService {

    String getMessage();

    void setMessage(String message);
}
Let's create the TwitterMessageService class, which implements the MessageService interface.

TwitterMessageService.java

package net.javaguides.spring.scope;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class TwitterMessageService implements MessageService {

    private String message;

    @Override
    public String getMessage() {
        return message;
    }

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

Annotation-Based Configuration - AppConfig.java

package net.javaguides.spring.scope;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "net.javaguides.spring")
public class AppConfig {
 
}
@ComponentScan annotation scans all beans whose class is annotated by the @Component annotation in a package specified by the basePackages attribute. 

Running Spring Application - Application.java

Let's create a main class and run an application.
package net.javaguides.spring.scope;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext  context = new AnnotationConfigApplicationContext(AppConfig.class);
        MessageService messageService = context.getBean(MessageService.class);
        messageService.setMessage("TwitterMessageService Implementation");
        System.out.println(messageService.getMessage());
  
        MessageService messageService1 = context.getBean(MessageService.class);
        System.out.println(messageService1.getMessage());
        context.close();
    }
}

Output

TwitterMessageService Implementation
TwitterMessageService Implementation
Let's develop the same example using Java-based configuration with @Bean annotation. 

Spring @Scope Annotation + Singleton Scope + @Bean Example

MessageService.java

package net.javaguides.spring.scope;

public interface MessageService {

    String getMessage();

    void setMessage(String message);
}
Let's create the TwitterMessageService class, which implements the MessageService interface. 

TwitterMessageService.java

package net.javaguides.spring.scope;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

public class TwitterMessageService implements MessageService {

    private String message;

    @Override
    public String getMessage() {
        return message;
    }

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

Java-based Configuration - AppConfig.java

Declare the above beans in the Java-based configuration class.
package net.javaguides.spring.scope;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class AppConfig {

    @Bean
    @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
    public MessageService messageService() {
        return new TwitterMessageService();
    }
}

Running Spring Application - Application.java

Let's create a main class and run an application.
package net.javaguides.spring.scope;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext  context = new AnnotationConfigApplicationContext(AppConfig.class);
        MessageService messageService = context.getBean(MessageService.class);
        messageService.setMessage("TwitterMessageService Implementation");
        System.out.println(messageService.getMessage());
  
        MessageService messageService1 = context.getBean(MessageService.class);
        System.out.println(messageService1.getMessage());
        context.close();
    }
}

Output

TwitterMessageService Implementation
TwitterMessageService Implementation
The source code of this article is available on my GitHub repository https://github.com/RameshMF/spring-core-tutorial

Related Spring and Spring Boot Annotations

Comments