In-Memory Data Management
Relevant source files
The following files were used as context for generating this wiki page:- complete/src/main/java/com/example/restservice/GreetingController.java
- complete/src/main/java/com/example/restservice/Greeting.java
- README.adoc
- complete/src/test/java/com/example/restservice/GreetingControllerTests.java
- complete/src/main/java/com/example/restservice/RestServiceApplication.java
- complete/pom.xml
Introduction
This project implements a simple form of in-memory data management to maintain state within a single-instance RESTful web service. The primary piece of data managed in memory is a request counter, which is used to generate a unique ID for each greeting. This state is volatile and is reset every time the application restarts.
The management is handled entirely within the GreetingController class. It utilizes a thread-safe AtomicLong to ensure that the ID is unique even with concurrent requests. This approach is suitable for a demonstration service but does not provide data persistence, meaning the counter state is lost upon application shutdown.
Sources: complete/src/main/java/com/example/restservice/GreetingController.java:12, README.adoc:117-120
Architecture
The in-memory data management is centered around the GreetingController, which holds the state. The architecture is straightforward: an incoming HTTP request is handled by the controller, which then accesses its internal state (the counter) to generate a new data object (Greeting) before returning it as a JSON response.
Sources: complete/src/main/java/com/example/restservice/GreetingController.java, complete/src/main/java/com/example/restservice/Greeting.java
Component Interaction
The diagram below illustrates the relationship between the key components involved in handling a request and managing the in-memory state.
State Management
State is managed via a single private field within the GreetingController.
Sources: complete/src/main/java/com/example/restservice/GreetingController.java:12
The Counter
The core of the in-memory state is the counter field.
// complete/src/main/java/com/example/restservice/GreetingController.java:12
private final AtomicLong counter = new AtomicLong();
- Type:
java.util.concurrent.atomic.AtomicLong - Purpose: To generate a unique, monotonically increasing ID for each greeting.
- Scope: It is an instance variable of the
GreetingController. Since Spring Boot typically creates controllers as singletons, this counter is shared across all requests handled by this application instance. - Thread Safety: The use of
AtomicLongensures that incrementing the counter is an atomic operation, making it safe to use in a multi-threaded environment without explicit locking. - Lifecycle: The counter is initialized to 0 when the
GreetingControlleris instantiated and is reset to 0 every time the application restarts.
The counter is incremented and its new value is retrieved with each call to the greeting method using counter.incrementAndGet().
Sources: complete/src/main/java/com/example/restservice/GreetingController.java:12,16, README.adoc:117-120
Data Model
The data produced and returned by the service is represented by the Greeting record. This is a simple, immutable data carrier class.
Sources: complete/src/main/java/com/example/restservice/Greeting.java
Greeting Record
The Greeting class is defined as a Java record, which automatically provides fields, a constructor, and accessor methods.
// complete/src/main/java/com/example/restservice/Greeting.java:3
public record Greeting(long id, String content) { }
The diagram below shows the structure of the Greeting class.
The fields of the Greeting object are detailed in the table below.
| Field | Type | Description |
|---|---|---|
id | long | A unique identifier for the greeting, generated by the in-memory counter. |
content | String | The textual representation of the greeting message, e.g., "Hello, World!". |
Sources: complete/src/main/java/com/example/restservice/Greeting.java:3, README.adoc:52-54
Request Flow for State Update
The following sequence diagram shows how a request to the /greeting endpoint interacts with the GreetingController to update and use the in-memory counter.
This flow is validated by the integration tests, which check that the id increments on subsequent calls and that the content is correctly formatted.
Sources: complete/src/main/java/com/example/restservice/GreetingController.java:15-17, complete/src/test/java/com/example/restservice/GreetingControllerTests.java, README.adoc:10-24
Summary
The in-memory data management in this service is intentionally minimalistic, relying on a thread-safe AtomicLong field within a singleton controller. This design provides a unique, incrementing ID for each request during the application's runtime. While this demonstrates state management within a Spring application, it is a volatile solution where all state is lost on restart, making it unsuitable for any system requiring data persistence. The project uses standard Spring Boot features and the spring-boot-starter-web dependency to achieve this behavior without complex configuration.
Sources: complete/src/main/java/com/example/restservice/GreetingController.java, complete/pom.xml:21-24