Backend Development 7 min read

Implement Persistent Chat Memory in Spring Boot 3 with Spring AI Advisors

This article demonstrates how to enable conversation memory and history in Spring Boot 3 applications using Spring AI's Advisor API, covering environment setup, Maven dependencies, configuration, code examples for advisors, unique chat IDs, history retrieval, and optional database persistence.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Implement Persistent Chat Memory in Spring Boot 3 with Spring AI Advisors

Environment

Spring Boot 3.4.2

1. Introduction

When interacting with Chat models (e.g., Wenxin Yiyan, Tongyi Qianwen, Chat‑DeepSeek), memory and history are essential for recalling past user inputs and topics, enabling more accurate responses. Without memory, each conversation is independent.

With conversation memory enabled, the dialogue becomes continuous.

2. Practical Example

2.1 Environment Preparation

We use Alibaba's Chat model.

<code><dependency>
  <groupId>com.alibaba.cloud.ai</groupId>
  <artifactId>spring-ai-alibaba-starter</artifactId>
  <version>1.0.0-M6.1</version>
</dependency></code>

2.2 Conversation Memory

Spring AI provides a default memory Advisor. Add it when building the ChatClient :

<code>var chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(
        new MyAdvisor(),
        ...
    )
    .build();</code>

Configure two advisors: one for request logging and one for memory.

<code>@Bean
ChatClient chatClient(ChatClient.Builder ccb, ChatMemory cm) {
    List<Advisor> advisors = List.of(
        new SimpleLoggerAdvisor(), // request log
        new MessageChatMemoryAdvisor(cm) // conversation memory
    );
    return ccb.defaultAdvisors(advisors).build();
}</code>

Define a ChatMemory bean (in‑memory implementation):

<code>@Bean
ChatMemory chatMemory() {
    return new InMemoryChatMemory();
}</code>

2.3 Unique Conversation IDs

To avoid sharing the same context across users, pass a unique chatId for each request:

<code>@GetMapping("/{chatId}")
public String chat(String prompt, @PathVariable String chatId) {
    String result = this.chatClient.prompt(prompt)
        .advisors(a -> a
            .param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
            .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
        .call()
        .content();
    return result;
}</code>

Now each conversation is isolated.

2.4 Conversation History

Retrieve past messages via ChatMemory :

<code>@RestController
@RequestMapping("/history")
public class ChatHistoryController {
    private final ChatMemory chatMemory;
    public ChatHistoryController(ChatMemory chatMemory) { this.chatMemory = chatMemory; }

    @GetMapping("/{chatId}")
    public ResponseEntity<?> queryChatId(@PathVariable String chatId) {
        List<MessageVO> result = this.chatMemory.get(chatId, 10).stream()
            .map(message -> new MessageVO(parseMessageType(message.getMessageType()), message.getText()))
            .collect(Collectors.toList());
        return ResponseEntity.ok(result);
    }

    public static String parseMessageType(MessageType type) {
        return switch (type) {
            case USER -> "user";
            case ASSISTANT -> "assistant";
            default -> throw new IllegalArgumentException("Unexpected value: " + type);
        };
    }
}
</code>

2.5 Persistence to Database

If you need to store chat history, add the JDBC memory starter:

<code><dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-starter-model-chat-memory-jdbc</artifactId>
</dependency></code>

Note: This feature is available from version 1.0.0‑M7.

For the full article, see the accompanying PDF with 116 Spring Boot practical cases.

backendJavaSpring BootSpring AIAdvisorChat Memory
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.