Add AI to Your Java Project in Just a Few Lines with Spring AI 2.0

Spring AI 2.0 lets Java developers integrate large‑language‑model capabilities with minimal code by adding a starter, configuring model parameters, injecting a ChatClient bean, and optionally enabling Redis‑backed chat memory for multi‑turn conversations, all demonstrated with runnable examples and screenshots.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Add AI to Your Java Project in Just a Few Lines with Spring AI 2.0

Spring AI Overview

Spring AI is an official Spring extension that abstracts AI model access, allowing developers to use familiar Spring patterns (starters, beans, dependency injection) to build AI‑enabled applications without dealing with low‑level HTTP or JSON handling.

Project Integration

Add the Spring AI BOM (version 2.0.0) to pom.xml to manage versions.

Include the OpenAI starter (compatible with DeepSeek) and the WebFlux starter for reactive streaming.

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-bom</artifactId>
      <version>${spring-ai.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<!-- Spring AI OpenAI Starter -->
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

<!-- SpringBoot WebFlux dependency -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

Configure the model in application.yaml (using DeepSeek‑v4‑pro as an example).

spring:
  ai:
    openai:
      # DeepSeek compatible endpoint
      base-url: https://api.deepseek.com
      api-key: ${DEEPSEEK_API_KEY}
      chat:
        model: deepseek-v4-pro

Create a configuration class that defines a ChatClient bean.

@Configuration
public class SpringAIConfig {
    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder.build();
    }
}

Implementing Chat Functionality

A ChatController provides three endpoints: /chat/call – synchronous call using ChatClient.call(). /chat/stream – SSE streaming using ChatClient.stream() and returning MediaType.TEXT_EVENT_STREAM_VALUE.

Additional endpoints for retrieving and clearing chat history.

@RestController
@RequestMapping("/chat")
public class ChatController {
    private final ChatClient chatClient;
    private final ChatMemory chatMemory;

    @PostMapping("/call")
    public String call(@RequestParam String question, @RequestParam String conversationId) {
        List<Message> history = chatMemory.get(conversationId);
        chatMemory.add(conversationId, List.of(new UserMessage(question)));
        String response = chatClient.prompt()
                               .messages(history)
                               .user(question)
                               .call()
                               .content();
        chatMemory.add(conversationId, List.of(new AssistantMessage(response)));
        return response;
    }

    @PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ChatEventDto> stream(@RequestParam String question, @RequestParam String conversationId) {
        List<Message> history = chatMemory.get(conversationId);
        chatMemory.add(conversationId, List.of(new UserMessage(question)));
        StringBuilder full = new StringBuilder();
        return chatClient.prompt()
                         .messages(history)
                         .user(question)
                         .stream()
                         .content()
                         .map(content -> {
                             full.append(content);
                             return ChatEventDto.builder()
                                 .eventType(ChatEventType.DATA.getValue())
                                 .eventData(content)
                                 .build();
                         })
                         .concatWith(Flux.just(ChatEventDto.builder()
                             .eventType(ChatEventType.STOP.getValue())
                             .build()))
                         .doOnComplete(() -> {
                             if (!full.isEmpty()) {
                                 chatMemory.add(conversationId, List.of(new AssistantMessage(full.toString())));
                             }
                         });
    }

    // /history and /clearHistory endpoints omitted for brevity
}

Adding Chat Memory with Redis

Redis‑Stack 7.4.0 is required for the built‑in vector store. Run it via Docker:

docker run --name redis-stack \
  -p 6379:6379 \
  -p 8001:8001 \
  -d redis/redis-stack:7.4.0-v8

Add the Redis chat‑memory starter to pom.xml.

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

Configure Redis connection in application.yaml.

spring:
  ai:
    chat:
      memory:
        redis:
          host: 192.168.3.101
          port: 6379
          time-to-live: 24h
          key-prefix: spring-chat

Define beans for RedisChatMemoryRepository and ChatMemory (using MessageWindowChatMemory with a max of 100 messages).

@Configuration
public class SpringAIConfig {
    @Value("${spring.ai.chat.memory.redis.host}")
    private String redisHost;
    @Value("${spring.ai.chat.memory.redis.port}")
    private int redisPort;

    @Bean
    public RedisChatMemoryRepository redisChatMemoryRepository() {
        RedisClient client = RedisClient.builder()
                                      .hostAndPort(redisHost, redisPort)
                                      .build();
        return RedisChatMemoryRepository.builder()
                                        .jedisClient(client)
                                        .build();
    }

    @Bean
    public ChatMemory chatMemory(RedisChatMemoryRepository repository) {
        return MessageWindowChatMemory.builder()
                                    .chatMemoryRepository(repository)
                                    .maxMessages(100)
                                    .build();
    }
}

Testing the Service

Using Postman, the synchronous /chat/call endpoint returns the full response at once, while the streaming /chat/stream endpoint delivers incremental JSON events. The UI built with TDesign’s Chatbot component shows multi‑turn interactions, and the Redis console confirms that conversation history is persisted.

Conclusion

Spring AI 2.0 reduces the effort to embed LLM capabilities in a Spring Boot application to three steps: add the starter, configure model credentials, and inject a ChatClient. By adding the optional Redis‑backed ChatMemory, developers obtain true multi‑turn conversation memory without writing custom persistence code.

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.

JavaRedisChatGPTSpring BootSpring AIai-integrationchat-memory
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

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.