Micronaut Scope Types
Learn about the available scopes: Singleton, Prototype, Request, Refreshable, Context...
On this guide
In this section
Introduction
Micronaut features an extensible bean scoping mechanism based on JSR-330.
What you will need
To complete this guide, you will need the following:
-
Some time on your hands
-
A decent text editor or IDE (e.g. IntelliJ IDEA)
-
JDK 21 or greater installed with
JAVA_HOMEconfigured appropriately
Solution
We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.
-
Download and unzip the source
Writing the Application
Create an application using the Micronaut Command Line Interface or with Micronaut Launch.
mn create-app example.micronaut.micronautguide \
--features=management,validation,junit-params \
--build=maven \
--lang=java \
--test=junit|
Note
|
If you don’t specify the --build argument, Gradle with the Kotlin DSL is used as the build tool. If you don’t specify the --lang argument, Java is used as the language.If you don’t specify the --test argument, JUnit is used for Java and Kotlin, and Spock is used for Groovy.
|
The previous command creates a Micronaut application with the default package example.micronaut in a directory named micronautguide.
If you use Micronaut Launch, select Micronaut Application as application type and add management, validation, and junit-params features.
|
Note
|
If you have an existing Micronaut application and want to add the functionality described here, you can view the dependency and configuration changes from the specified features, and apply those changes to your application. |
Scenario
We use the following scenario to talk about the different types of scopes.
The following @Controller injects two collaborators.
Each collaborator has an injection point for a bean of type Robot.
Let’s discuss how the application behaves depending on the scope used for the bean of type Robot.
Singleton
Singleton scope indicates only one instance of the bean will exist.
To define a singleton, annotate a class with jakarta.inject.Singleton at the class level.
The following class creates a unique identifier in the constructor. This identifier allows us to identify how many Robot instances are used.
Singleton Test
To use the testing features described in this section, add the following dependency to your build file:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>The following test verifies @Singleton behavior.
Prototype
Prototype scope indicates that a new instance of the bean is created each time it is injected
Let’s use @Prototype instead of @Singleton.
Prototype Tests
The following test verifies the behavior of Prototype scope.
Request
@RequestScope scope is a custom scope that indicates a new instance of the bean is created and associated with each HTTP request
Request Tests
The following test verifies the behavior of @RequestScope scope.
Refreshable
Refreshable scope is a custom scope that allows a bean’s state to be refreshed via the /refresh endpoint.
Your application needs the management dependency to enable the refresh endpoint.
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-management</artifactId>
<scope>compile</scope>
</dependency>Refreshable Tests
The following test enables the refresh endpoint and verifies the behavior of @Refreshable
@Context
Context scope indicates that the bean will be created at the same time as the ApplicationContext (eager initialization)
The following example uses @Context in combination with @ConfigurationProperties.
The result is validation being performed on the Application Context start-up.
package example.micronaut;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.exceptions.BeanInstantiationException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.*;
class ContextTest {
@Test
void lifeCycleOfClassesAnnotatedWithAtContextIsBoundToThatOfTheBeanContext() {
Executable e = () -> ApplicationContext.run(Collections.singletonMap("framework.language", "scala"));
BeanInstantiationException thrown = assertThrows(BeanInstantiationException.class, e);
assertTrue(thrown.getMessage().contains("language - must match \"groovy|java|kotlin\""));
}
}Other scopes
Micronaut Framework ships with other built-in scopes:
@Infrastructure
@Infrastructure scope represents a bean that cannot be overridden or replaced using @Replaces because it is critical to the functioning of the system.
@ThreadLocal
@ThreadLocal scope is a custom scope that associates a bean per thread via a ThreadLocal
Next Steps
Read more about Scopes in the Micronaut Framework.
Help with the Micronaut Framework
The Micronaut Foundation sponsored the creation of this Guide. A variety of consulting and support services are available.
License
|
Note
|
All guides are released with an Apache License 2.0 for the code and a Creative Commons Attribution 4.0 license for the writing and media (images). |