Spring @Scope Annotation with Prototype Scope Example

In this article, we will discuss how to use @Scope annotation with Prototype scope in the Spring boot application.

YouTube Video - Spring @Scope Annotation

Overview

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

The @Scope annotation can use with all Spring bean scopes:
  1. Singleton: only one instance of the bean is created and shared across the entire application. This is the default scope.

  2. Prototype: a new instance of the bean is created every time it is requested.

  3. Request: a new instance of the bean is created for each HTTP request. It is only applicable to web applications.

  4. Session: a new instance of the bean is created for each HTTP session. It is only applicable to web applications.

  5. Application: a single instance of the bean is created and shared across the entire application context. It is only applicable to web applications.

In this article, we will discuss how to use @Scope annotation with Prototype scope with an example.
When a spring bean is scoped as a prototype, the Spring IoC container creates a new bean instance every time when a request is made for that bean.
We can define the scope of a bean as a prototype using the scope="prototype" attribute of the element or using @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) annotation.
We will demonstrate this example using Annotation based (@Component) as well as Java-based configuration(@Bean).

Spring @Scope Annotation + Prototype Scope + @Component Example

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

Create a Simple Maven Project

Create a simple maven project using your favorite IDE and refer below section for packaging structure. If you are new to maven then 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.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.6</version>
        </dependency>

    </dependencies>
</project>
Create MessageService interface as follows.

MessageService.java

package net.javaguides.spring.scope;

public interface MessageService {

    String getMessage();

    void setMessage(String message);
}
Let's create 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_PROTOTYPE)
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
null
Let's develop the same example using Java-based configuration with @Bean annotation.

Spring @Scope Annotation + Prototype Scope + @Bean Example

Create MessageService interface as follows.

MessageService.java

package net.javaguides.spring.scope;

public interface MessageService {

    String getMessage();

    void setMessage(String message);
}
Let's create 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 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_PROTOTYPE)
    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
null
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