DEV Community

Said Olano
Said Olano

Posted on

Spring AI + OpenAI: Complete Integration Guide for Java (2026)

Spring AI + OpenAI: Complete Integration Guide for Java Applications

Introduction

Spring AI is an initiative from the Spring ecosystem that provides a unified abstraction for integrating Large Language Models (LLMs) into Java applications. In this article, we'll explore how to build a Spring Boot application that seamlessly integrates with OpenAI, enabling you to create intelligent applications with chat conversations, embeddings generation, and real-time information processing.

In recent years, artificial intelligence has become a fundamental component in software development. However, integrating LLMs into enterprise Java applications has been challenging due to the lack of standard abstractions. Spring AI solves this problem by providing:

  • Unified abstraction for multiple AI providers (OpenAI, Anthropic, Azure, Google, etc.)
  • Native support for Spring Boot with autoconfiguration
  • Context management and conversation memory
  • RAG integration (Retrieval-Augmented Generation)
  • Security and output validation
  • Token management and cost tracking

What is Spring AI?

Spring AI is a Spring framework that simplifies the integration of language models into Java applications. It acts as an abstraction layer between your application and AI providers, allowing you to switch providers without modifying your business logic.

Key Features

1. ChatClient API
The main interface for interacting with LLMs. Provides simple methods to send prompts and receive responses.

2. Multiple Provider Support

  • OpenAI (GPT-4, GPT-3.5-turbo)
  • Azure OpenAI
  • Anthropic Claude
  • Google Gemini
  • Ollama (local)

3. Autoconfiguration
Spring Boot automatically detects your API key and configures the client without boilerplate code.

4. Context Management
Maintains conversation history to create more natural chat experiences.

5. Embeddings and Vector Databases
Support for generating embeddings and integrating with vector databases like Weaviate, Milvus, and Chroma.

Prerequisites

Before getting started, you'll need:

Project Setup

Step 1: Create the Base Project

mvn archetype:generate -DgroupId=mx.development.josesaid.ai \\
  -DartifactId=spring-ai-openai-demo \\
  -DarchetypeArtifactId=maven-archetype-quickstart
Enter fullscreen mode Exit fullscreen mode

Step 2: Update pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/>
    </parent>

    <groupId>mx.development.josesaid.ai</groupId>
    <artifactId>spring-ai-openai-demo</artifactId>
    <version>1.0.0</version>
    <name>spring-ai-openai-demo</name>
    <description>Spring AI + OpenAI Integration Demo</description>

    <properties>
        <java.version>21</java.version>
        <spring-ai.version>1.0.0</spring-ai.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring AI OpenAI -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- Testing -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure application.yml

spring:
  application:
    name: spring-ai-openai-demo
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o-mini
          temperature: 0.7
          max-tokens: 2048

server:
  port: 8080
  servlet:
    context-path: /api
Enter fullscreen mode Exit fullscreen mode

Implementation: ChatRunner Component

Here's the heart of our Spring AI integration. The ChatRunner component demonstrates how to create a fully functional chat client that interacts with OpenAI through Spring AI. This component leverages Spring Boot's CommandLineRunner to execute custom code when the application starts. The magic happens in the runner() method where we inject the ChatClient.Builder (auto-configured by Spring AI), build the client, and make a call to OpenAI to demonstrate the integration.

Without Spring AI, you'd need to manually manage HTTP calls, JSON serialization, error handling, token management, and authentication configuration. Spring AI abstracts all this complexity, allowing you to focus purely on your business logic. The flow is elegant: you build the client, send a prompt using the fluent API, call .call() for a synchronous request to OpenAI, and extract the response with .content().

package mx.development.josesaid.ai.spring.ai.demo;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class ChatRunner {

    @Bean
    public CommandLineRunner runner(ChatClient.Builder builder) {
        return (String[] args) -> {
            System.out.println();
            System.out.println("Provider - OpenAI");

            // Build the chat client with Spring AI
            ChatClient chatClient = builder.build();

            // Perform a simple conversation
            String response = chatClient
                .prompt("What is Spring AI?")
                .call()
                .content();

            // Display the response
            System.out.println(response);
        };
    }
}
Enter fullscreen mode Exit fullscreen mode

Building a Complete REST API

While ChatRunner is useful for initial testing, building a real REST API is more practical for production applications:

package mx.development.josesaid.ai.spring.ai.demo.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/chat")
@RequiredArgsConstructor
public class ChatController {

    private final ChatClient chatClient;

    @PostMapping("/message")
    public ChatResponse sendMessage(@RequestBody ChatRequest request) {
        String response = chatClient
            .prompt(request.getMessage())
            .call()
            .content();

        return new ChatResponse(response);
    }

    @GetMapping("/health")
    public String health() {
        return "Spring AI + OpenAI is running";
    }
}

// DTO Classes
record ChatRequest(String message) {}
record ChatResponse(String message) {}
Enter fullscreen mode Exit fullscreen mode

Error Handling and Validation

In production, you need to handle errors gracefully:

@RestController
@RequestMapping("/chat")
@RequiredArgsConstructor
public class ChatController {

    private final ChatClient chatClient;

    @PostMapping("/message")
    public ResponseEntity<?> sendMessage(@RequestBody ChatRequest request) {
        try {
            if (request.message() == null || request.message().isBlank()) {
                return ResponseEntity.badRequest()
                    .body(new ErrorResponse("Message cannot be empty"));
            }

            String response = chatClient
                .prompt(request.message())
                .call()
                .content();

            return ResponseEntity.ok(new ChatResponse(response));
        } catch (Exception e) {
            return ResponseEntity.status(500)
                .body(new ErrorResponse("Error processing message: " + e.getMessage()));
        }
    }
}

record ErrorResponse(String error) {}
Enter fullscreen mode Exit fullscreen mode

Environment Variable Configuration

To keep your API key secure, use environment variables. In IntelliJ, the best practice is to use VM options:

VM Options (Recommended):

-Dspring.ai.openai.api-key=sk-proj-YOUR_KEY_HERE
Enter fullscreen mode Exit fullscreen mode

Environment Variables:

OPENAI_API_KEY=sk-proj-YOUR_KEY_HERE
Enter fullscreen mode Exit fullscreen mode

application.yml:

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
Enter fullscreen mode Exit fullscreen mode

Testing with curl

Once the application is running at http://localhost:8080/api:

curl -X POST http://localhost:8080/api/chat/message \\
  -H "Content-Type: application/json" \\
  -d '{"message":"What are the advantages of Spring AI?"}'
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases

  1. Customer Support Chatbot - Integrate with vector databases for context-aware support
  2. Sentiment Analysis - Process customer reviews automatically
  3. Content Generation - Create product descriptions, articles, and emails
  4. Semantic Search - Implement intelligent search using embeddings
  5. Information Processing - Extract structured data from unstructured text

Best Practices

  1. Never hardcode API keys - always use environment variables
  2. Implement Rate Limiting - OpenAI has request limits
  3. Cache results - reuse responses for identical prompts
  4. Monitor costs - each call has a cost
  5. Validate inputs - sanitize user prompts
  6. Implement timeouts - OpenAI calls can be slow
  7. Use streaming - improve UX for long responses

Conclusion

Spring AI democratizes access to advanced LLMs for Java developers. The combination of Spring Boot with Spring AI creates a powerful stack for building enterprise AI applications. Whether you're building chatbots, recommendation systems, or analysis tools, Spring AI provides the foundation you need.

Next Steps:

  • Explore RAG (Retrieval-Augmented Generation)
  • Integrate vector databases (Weaviate, Milvus)
  • Implement function calling
  • Experiment with different models

springai #openai #java #springboot #ai #llm #microservices

Top comments (0)