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:
- Java 21+ (recommended)
- Maven or Gradle for dependency management
- OpenAI API Key (https://platform.openai.com/account/api-keys)
- IntelliJ IDEA or VS Code as your IDE
- Maven >= 3.6 or Gradle >= 7.0
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
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>
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
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);
};
}
}
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) {}
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) {}
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
Environment Variables:
OPENAI_API_KEY=sk-proj-YOUR_KEY_HERE
application.yml:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
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?"}'
Real-World Use Cases
- Customer Support Chatbot - Integrate with vector databases for context-aware support
- Sentiment Analysis - Process customer reviews automatically
- Content Generation - Create product descriptions, articles, and emails
- Semantic Search - Implement intelligent search using embeddings
- Information Processing - Extract structured data from unstructured text
Best Practices
- Never hardcode API keys - always use environment variables
- Implement Rate Limiting - OpenAI has request limits
- Cache results - reuse responses for identical prompts
- Monitor costs - each call has a cost
- Validate inputs - sanitize user prompts
- Implement timeouts - OpenAI calls can be slow
- 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
Top comments (0)