@Scope
annotation with Prototype scope in a Spring Boot application.Overview
The @Scope
annotation is used to define the scope of a @Component
class or a @Bean
definition. The @Scope
annotation can be used with all Spring bean scopes:
- Singleton: Only one instance of the bean is created and shared across the entire application. This is the default scope.
- Prototype: A new instance of the bean is created every time it is requested.
- Request: A new instance of the bean is created for each HTTP request. It is only applicable to web applications.
- Session: A new instance of the bean is created for each HTTP session. It is only applicable to web applications.
- 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 the @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 a request is made for that bean. We can define the scope of a bean as a prototype using the @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 @Scope
annotation with a prototype scope in a Spring application.
1. Create a Simple Maven Project
Create a simple Maven project using your favourite IDE. Below is the project structure for your reference:
2. The pom.xml File
Make sure to use Java 17 or later for Spring Framework 6:
<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>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.6</version>
</dependency>
</dependencies>
</project>
3. Create Spring Beans
MessageService Interface
package net.javaguides.spring.scope;
public interface MessageService {
String getMessage();
void setMessage(String message);
}
This interface defines two methods: getMessage()
and setMessage(String message)
. Any class that implements this interface will need to provide implementations for these methods.
TwitterMessageService Class
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;
}
}
In this class:
@Component
annotation tells Spring that this class is a Spring component.@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
annotation specifies that this bean should be scoped as a prototype.getMessage()
returns the current message.setMessage(String message)
sets the current message.
4. Annotation-Based Configuration
AppConfig Class
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 {
}
In this class:
@Configuration
indicates that this class contains Spring bean definitions.@ComponentScan(basePackages = "net.javaguides.spring")
tells Spring to scan the specified package for components (i.e., classes annotated with@Component
).
5. Running Spring Application
Application Class
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();
}
}
In this class:
AnnotationConfigApplicationContext
is used to create and manage the Spring application context.context.getBean(MessageService.class)
retrieves a bean of typeMessageService
from the Spring context.- The first bean (
messageService
) sets and prints a message. - The second bean (
messageService1
) retrieves and prints the message.
Output
TwitterMessageService Implementation
null
Explanation:
- The first bean (
messageService
) sets the message to "TwitterMessageService Implementation" and prints it. - The second bean (
messageService1
) is a new instance (because of the prototype scope) and has no message set, so it printsnull
.
Spring @Scope Annotation + Prototype Scope + @Bean Example
Create MessageService Interface
MessageService Interface
package net.javaguides.spring.scope;
public interface MessageService {
String getMessage();
void setMessage(String message);
}
This interface remains the same as in the previous example.
Create TwitterMessageService Class
TwitterMessageService Class
package net.javaguides.spring.scope;
public class TwitterMessageService implements MessageService {
private String message;
@Override
public String getMessage() {
return message;
}
@Override
public void setMessage(String message) {
this.message = message;
}
}
This class remains the same, but without @Component
and @Scope
annotations since we will configure it using Java-based configuration.
Java-based Configuration
AppConfig 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();
}
}
In this class:
@Bean
annotation tells Spring that this method returns a Spring bean.@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
specifies that this bean should be scoped as a prototype.
Running Spring Application
Application Class
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();
}
}
This class remains the same as in the previous example.
Output
TwitterMessageService Implementation
null
Explanation:
- The first bean (
messageService
) sets the message to "TwitterMessageService Implementation" and prints it. - The second bean (
messageService1
) is a new instance (because of the prototype scope) and has no message set, so it printsnull
.
Conclusion
In this article, we demonstrated how to use the @Scope
annotation with Prototype scope in
Spring Boot applications. Using the prototype scope, we ensure that a new instance of the bean is created each time it is requested. This is particularly useful for beans that are stateful and need to be re-instantiated with every use.
Related Spring and Spring Boot Annotations
- Spring Boot @Bean Annotation Example
- Spring @Qualifier Annotation Example
- Spring @Autowired Annotation with Example
- Spring @Bean Annotation with Example
- Spring @Configuration Annotation with Example
- Spring @PropertySource Annotation with Example
- Spring @Import Annotation with Example
- Spring @ImportResource Annotation Example
- Spring - @Lazy Annotation Example
- Spring - @Primary Annotation Example
- Spring @PostConstruct and @PreDestroy Example
- Spring @Repository Annotation
- Spring @Service Annotation
- The Spring @Controller and @RestController Annotations
- Spring Boot @Component, @Controller, @Repository and @Service
- Spring @Scope annotation with Prototype Scope Example
- Spring @Scope annotation with Singleton Scope Example
- Spring Boot @PathVariable
- Spring Boot @ResponseBody
- Spring @RequestBody - Binding Method Parameters to Request Body
- Spring Boot @ResponseStatus Annotation
- Spring Boot - Creating Asynchronous Methods using @Async Annotation
- @SpringBootTest Spring Boot Example
- @SpringBootTest vs @WebMvcTest
- @DataJpaTest Spring Boot Example
- Spring @PostConstruct and @PreDestroy Example
- Spring @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping
- Spring Boot @EnableAutoConfiguration Annotation with Example
- Spring Boot @SpringBootApplication Annotation with Example
Comments
Post a Comment
Leave Comment