Add Chat Memory and Session Isolation to SpringBoot AI with LangChain4j

This guide demonstrates how to integrate LangChain4j into a SpringBoot application to enable multi‑turn chat memory and per‑user session isolation using @MemoryId, configuring ChatMemoryProvider, updating the AI service interface, and testing with curl requests.

The Dominant Programmer
The Dominant Programmer
The Dominant Programmer
Add Chat Memory and Session Isolation to SpringBoot AI with LangChain4j

SpringBoot can be extended with LangChain4j to provide fast AI dialogue, but the initial setup lacks conversation memory and user isolation. LangChain4j solves this by using the @MemoryId parameter to distinguish separate chat histories.

AiServices in LangChain4j

AiServices allows declarative construction of AI services with annotations for memory and system prompts.

import dev.langchain4j.service.AiService;</code><code>import dev.langchain4j.service.SystemMessage;</code><code>@AiService</code><code>public interface Assistant {</code><code>    @SystemMessage("你是一位知识渊博的AI助手,请用中文友好地回答用户的问题。")</code><code>    String chat(String userMessage);</code><code>}

The interface can be injected like a regular Spring bean.

@RestController</code><code>public class AssistantController {</code><code>    private final Assistant assistant;</code><code>    public AssistantController(Assistant assistant) {</code><code>        this.assistant = assistant;</code><code>    }</code><code>    @GetMapping("/ai/assistant")</code><code>    public String assistantChat(@RequestParam(value = "message") String message) {</code><code>        return assistant.chat(message);</code><code>    }</code><code>}

ChatMemory (Conversation Memory)

To support multi‑turn dialogue, integrate a ChatMemory component. MessageWindowChatMemory provides a sliding‑window memory suitable for development and testing.

@MemoryId and Session Isolation

LangChain4j’s AiServices offers elegant session isolation: adding a method parameter annotated with @MemoryId lets the framework manage independent memories for each ID.

Implementation Steps

1. Modify the AI Service Interface

Add @MemoryId and @UserMessage to the chat method so that each user’s ID controls the memory window.

import dev.langchain4j.service.MemoryId;</code><code>import dev.langchain4j.service.SystemMessage;</code><code>import dev.langchain4j.service.UserMessage;</code><code>import dev.langchain4j.service.spring.AiService;</code><code>@AiService</code><code>public interface Assistant {</code><code>    @SystemMessage("你是一位知识渊博的AI助手,请用中文友好地回答用户的问题。")</code><code>    String chat(@MemoryId Long memoryId, @UserMessage String userMessage);</code><code>}

The key is the @MemoryId Long memoryId parameter; different IDs (e.g., user IDs) receive independent chat windows.

2. Configure a ChatMemoryProvider Bean

Create a configuration class that supplies a ChatMemory instance for each new memoryId. The example uses a sliding window that retains the latest 10 messages.

import dev.langchain4j.memory.chat.ChatMemoryProvider;</code><code>import dev.langchain4j.memory.chat.MessageWindowChatMemory;</code><code>import org.springframework.context.annotation.Bean;</code><code>import org.springframework.context.annotation.Configuration;</code><code>@Configuration</code><code>public class AiConfig {</code><code>    // Bean that provides an independent ChatMemory for each memoryId</code><code>    @Bean</code><code>    public ChatMemoryProvider chatMemoryProvider() {</code><code>        // MessageWindowChatMemory keeps up to 10 recent messages</code><code>        return memoryId -> MessageWindowChatMemory.withMaxMessages(10);</code><code>    }</code><code>}

This creates a MessageWindowChatMemory that stores at most ten recent messages per user.

3. Call the Service from a Controller

Inject the Assistant bean and obtain the user’s unique identifier (e.g., from the HTTP header X-User-Id) to pass as memoryId.

import com.badao.ai.service.Assistant;</code><code>import org.springframework.web.bind.annotation.*;</code><code>@RestController</code><code>public class AssistantController {</code><code>    private final Assistant assistant;</code><code>    public AssistantController(Assistant assistant) {</code><code>        this.assistant = assistant;</code><code>    }</code><code>    @GetMapping("/ai/assistant")</code><code>    public String chat(@RequestHeader("X-User-Id") Long userId,</code><code>                      @RequestParam(value = "message") String message) {</code><code>        // Pass user ID as memoryId</code><code>        return assistant.chat(userId, message);
</code><code>    }</code><code>}

The header X-User-Id supplies the unique identifier used for memory isolation.

4. Dependency Versions and Notes

Ensure langchain4j version ≥ 1.0.0‑beta3 in pom.xml; earlier versions may lack @UserMessage support. Example Maven snippet:

<parent></code><code>    <groupId>org.springframework.boot</groupId></code><code>    <artifactId>spring-boot-starter-parent</artifactId></code><code>    <version>3.2.5</version></code><code></parent></code><code><properties></code><code>    <java.version>17</java.version></code><code>    <langchain4j.version>1.0.0-beta3</langchain4j.version></code><code></properties></code><code><dependencyManagement></code><code>    <dependencies></code><code>        <dependency></code><code>            <groupId>dev.langchain4j</groupId></code><code>            <artifactId>langchain4j-community-bom</artifactId></code><code>            <version>${langchain4j.version}</version></code><code>        </dependency></code><code>        <!-- Alibaba DashScope integration starter --></code><code>        <dependency></code><code>            <groupId>dev.langchain4j</groupId></code><code>            <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId></code><code>        </dependency></code><code>        <!-- Explicit DashScope core dependency (starter may omit) --></code><code>        <dependency></code><code>            <groupId>dev.langchain4j</groupId></code><code>            <artifactId>langchain4j-community-dashscope</artifactId></code><code>        </dependency></code><code>    </dependencies></code><code></dependencyManagement>

Memory is stored in RAM; after a restart it is lost. For persistence, implement ChatMemoryStore and back it with MongoDB, Redis, etc.

In production, consider TokenWindowChatMemory, which evicts messages based on token count to better control costs.

5. Testing

Use an API tool (e.g., Postman) or curl to simulate two users. Example for user A (ID 1):

curl -H "X-User-Id: 1" "http://localhost:885/ai/assistant?message=你好,我叫张三。"

Then ask a follow‑up:

curl -H "X-User-Id: 1" "http://localhost:885/ai/assistant?message=我叫什么名字?"

The assistant should reply “张三”. For user B (ID 2), the same question should yield “I don’t know” because the memory is isolated.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaAISpringBootLangChain4jChatMemorySessionIsolation
The Dominant Programmer
Written by

The Dominant Programmer

Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi

0 followers
Reader feedback

How this landed with the community

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.