Spring AI Chat Memory Example
Chat memory allows AI applications to maintain conversational context between messages, which improves AI responses by enabling context-aware interactions. Spring AI provides tools to integrate chat memory efficiently with AI models such as OpenAI GPT. Let us delve into understanding Spring AI chat memory, with this thorough coding example.
1. What is Spring API and Chat Memory in Spring AI?
Spring API is part of the broader Spring ecosystem, providing developers with a robust framework to build scalable and maintainable applications in Java. Extending this ecosystem, Spring AI simplifies the integration of AI services such as OpenAI, allowing developers to leverage advanced language models with minimal setup. A key feature in Spring AI is chat memory, which acts as a storage mechanism to maintain conversation context, enabling the AI to remember previous messages and provide more coherent, context-aware responses. Chat memory can be implemented using various storage options, including in-memory storage for lightweight applications, JDBC repositories for relational database persistence, or other custom persistence mechanisms depending on the application’s requirements, ensuring flexibility and scalability in handling conversational data.
2. Code Example
The example demonstrates a Spring Boot REST API that interacts with OpenAI GPT models while maintaining chat memory.
2.1 Add Dependencies (pom.xml)
In your pom.xml, include the following dependencies:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
<version>latest__jar__version</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-model-chat-memory-repository-jdbc</artifactId>
<version>latest__jar__version</version>
</dependency>
2.2 How to get OpenAI API key?
- Visit the OpenAI website at https://platform.openai.com/signup to create an account if you don’t have one.
- Log in to your OpenAI account.
- Navigate to the API Keys section in the dashboard.
- Click on + Create new secret key to generate a new API key.
- Copy the generated API key and store it securely; you will need it in your Spring Boot application.
- Never expose your API key in public repositories or client-side code.
2.3 Creating a Bean Configuration
This section demonstrates how to configure Spring beans for chat memory, OpenAI service, and the chat client to enable AI-powered conversations.
package com.example.springai;
import com.theokanning.openai.OpenAiService;
import com.theokanning.openai.completion.chat.ChatCompletionRequest;
import com.theokanning.openai.completion.chat.ChatMessage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class ChatAiConfig {
@Value("${openai.api.key}") // Pull API key from application.properties
private String openAiApiKey;
// Chat Memory Repository Bean
@Bean
public ChatMemoryRepository chatMemoryRepository(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
JdbcChatMemoryRepositoryDialect dialect = new MysqlChatMemoryRepositoryDialect();
return JdbcChatMemoryRepository.builder()
.jdbcTemplate(jdbcTemplate)
.dialect(dialect)
.build();
}
// Chat Memory Bean
@Bean
public ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.maxMessages(10)
.build();
}
// OpenAI Service Bean
@Bean
public OpenAiService openAiService() {
return new OpenAiService(openAiApiKey);
}
// Chat Client Bean
@Bean
public ChatClient chatClient(ChatMemory chatMemory) {
return new ChatClient(chatMemory);
}
}
2.3.1 Code Explanation
The ChatAiConfig class is annotated with @Configuration, making it a Spring configuration class that sets up the necessary beans for an AI chat application. It injects the OpenAI API key from application.properties using @Value. A ChatMemoryRepository bean is defined, which uses JdbcTemplate with a MySQL-specific dialect to store chat history in a database. The ChatMemory bean is created using MessageWindowChatMemory, linking it to the repository and limiting the stored conversation to the last 10 messages. The OpenAiService bean is initialized with the API key to interact with OpenAI’s API, and a ChatClient bean is instantiated using the ChatMemory bean, allowing the application to maintain conversational context while communicating with the AI.
2.4 Creating a Chat Client
This section shows how to implement the ChatClient class, which handles sending user messages to the OpenAI API, storing conversation history in ChatMemory, and returning the AI’s response.
package com.example.springai.client;
import com.theokanning.openai.OpenAiService;
import com.theokanning.openai.completion.chat.ChatCompletionRequest;
import com.theokanning.openai.completion.chat.ChatMessage;
public class ChatClient {
private final ChatMemory chatMemory;
private final OpenAiService openAiService;
public ChatClient(ChatMemory chatMemory, OpenAiService openAiService) {
this.chatMemory = chatMemory;
this.openAiService = openAiService;
}
public String chat(String userMessage) {
chatMemory.addMessage(new ChatMessage("user", userMessage));
ChatCompletionRequest request = ChatCompletionRequest.builder()
.model("gpt-4")
.messages(chatMemory.getMessages())
.build();
var response = openAiService.createChatCompletion(request);
String aiMessage = response.getChoices().get(0).getMessage().getContent();
chatMemory.addMessage(new ChatMessage("assistant", aiMessage));
return aiMessage;
}
}
2.4.1 Code Explanation
The ChatClient class manages the interaction between a user and the AI by using ChatMemory to store conversation context and OpenAiService to call the OpenAI API. Its constructor injects both dependencies. The chat method first adds the user’s message to the chat memory, then builds a ChatCompletionRequest for the GPT-4 model using the stored messages. It sends the request through openAiService and retrieves the AI’s response. Finally, it stores the AI’s message in chat memory and returns it to the caller, ensuring that the conversation context is preserved for future exchanges.
2.5 Creating a Chat Controller
This section explains how to create the ChatController, a Spring @RestController that exposes a REST endpoint at /chat. It injects the ChatClient to handle user messages, accepts POST requests with the user message in the request body, forwards it to the chat client, and returns the AI-generated response.
package com.example.springai.controller;
import com.example.springai.client.ChatClient;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/chat")
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@PostMapping
public String chat(@RequestBody String userMessage) {
return chatClient.chat(userMessage);
}
}
2.5.1 Code Explanation
The ChatController class is a Spring @RestController that handles HTTP requests for the chat application. It is mapped to the /chat URL path using @RequestMapping. The constructor injects a ChatClient instance, which handles the AI interaction. The chat method is annotated with @PostMapping to accept POST requests containing a user message in the request body. It passes the user message to chatClient.chat(), retrieves the AI response, and returns it as the HTTP response, enabling real-time chat functionality via the REST API.
2.6 application.properties
Add your OpenAI API key in application.properties file.
openai.api.key=YOUR_OPENAI_API_KEY
2.7 Creating a Main File
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ChatApplication {
public static void main(String[] args) {
SpringApplication.run(ChatApplication.class, args);
}
}
2.7.1 Code Explanation
The ChatApplication class is the entry point for the Spring Boot application. It is annotated with @SpringBootApplication, which combines @Configuration, @EnableAutoConfiguration, and @ComponentScan, allowing Spring to automatically configure beans and scan components. The main method calls SpringApplication.run(ChatApplication.class, args), which starts the embedded server and initializes all the configured beans, including ChatClient, ChatController, and ChatAiConfig, enabling the chat REST API to handle incoming requests.
2.8 Code Run and Demo
To run the chat application, start the Spring Boot application by executing the ChatApplication main class. Once the application is running, it will start an embedded web server (by default on port 8080) and expose the REST endpoint /chat. You can test the chat functionality by sending a POST request with a JSON payload containing a user message to http://localhost:8080/chat using tools like Postman or cURL.
curl -X POST http://localhost:8080/chat \
-H "Content-Type: application/json" \
-d '{"userMessage":"Hello AI! How are you today?"}'
The application will forward the message to the ChatClient, which interacts with the OpenAI API while maintaining the conversation context in ChatMemory, and returns a context-aware AI response. Each response can be observed to adapt based on previous messages, demonstrating the effectiveness of chat memory in maintaining coherent and interactive AI conversations.
{
"aiMessage": "Hello! I'm doing well, thank you for asking. How can I assist you today?"
}
3. Conclusion
Chat memory in Spring AI enables AI applications to maintain context and provide intelligent responses, supporting multiple memory storage options that allow flexible implementation. This approach improves conversational AI experiences and can be extended for persistent chat history across sessions.




