Introduction to Spring AI
Build AI-powered applications using Spring's familiar programming patterns
Why Spring AI?
Simplifying AI Integration
Modern applications are increasingly using Large Language Models (LLMs) to build solutions that go beyond traditional programming capabilities. However, integrating these models into our applications often involves dealing with complex APIs, managing different AI providers, and handling various configuration challenges.
Spring AI, a new addition to the Spring ecosystem, addresses these issues by providing a common abstraction layer for working with different AI providers using the familiar Spring programming patterns.
Provider Agnostic
Eliminates the need for provider-specific SDKs
Easy Model Switching
Switch between models without changing application code
In this tutorial, we'll practically explore the fundamental concepts of Spring AI by building a basic image generation service.
The Rise of Spring AI
Java's Gateway to the AI Revolution
The development of AI in recent years has been incredibly rapid. It seems that if you don't pay attention for even six months, the effects of a new, large-scale model can surpass your imagination. Java hasn't had much success in the AI field historically, but Spring recently released a new module called Spring AI. This allows Java to finally get a piece of the AI pie!
The Spring AI project officially began in 2023, with a core purpose of providing a unified abstraction layer for integrating various AI Large Language Model (LLM) types and techniques into Spring applications.
Version Timeline
February 2024 - v0.8.0
First publicly available version
May 2025 - v1.0.0 GA
First stable General Availability release
August 2025 - v1.0.1
Deep MCP Java SDK integration, stability fixes
December 2025 - v1.1.1
Native OpenAI SDK, Claude Skills API, enhanced structured outputs
Key Features
Portable API
Works with OpenAI, Anthropic, Azure, Google, Amazon, Ollama
Vector Databases
Support for Pinecone, Redis, Cassandra, and more
RAG Support
Retrieval Augmented Generation workflows built-in
Function Calling
Execute client-side tools from AI model requests
Setting up the Project
Configure your Spring AI application
Project Overview
For our demonstration, we'll be building our image generation service using OpenAI's DALL-E model.
However, Spring AI supports models from various other providers like Anthropic, Stability AI, and even local models via Hugging Face or Ollama. We can choose the model that best suits our requirements as the specific AI model is irrelevant for this implementation.
2.1Dependencies
Let's start by adding the necessary dependency to our project's pom.xml file:
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId><version>1.0.1</version></dependency>The OpenAI starter dependency is a wrapper around OpenAI's APIs including Image Generation, and we'll use it to interact with the DALL-E model in our application.
2.2Configuring LLM Properties
Next, let's configure our OpenAI API key and chat model in the application.yaml file:
spring:ai:openai:api-key: ${OPENAI_API_KEY}image:options:model: dall-e-3size: 1024x1024
quality: hd• We use the $${} property placeholder to load the value of our API Key from an environment variable.
• We specify dall-e-3 as the model ID for image generation.
• We set the image size to 1024x1024 pixels for high-quality outputs.
Building an Image Generation Service
Create an AI-powered service using Spring AI
3.1Using ImageClient to Generate Images
In Spring AI, the ImageClient class serves as the main entry point for interacting with image generation models.
We can obtain an instance of it using the ImageClient bean, which the framework automatically creates for us based on the properties we configure in our application.yaml file.
Let's use this to create a new ImageGenerationService class:
privatefinalImageClient imageClient;ImageGenerationService(ImageClient imageClient){this.imageClient = imageClient;}Stringgenerate(){ImagePrompt prompt =newImagePrompt("A futuristic cityscape at sunset with flying cars");ImageResponse response = imageClient.call(prompt);return response.getResult().getOutput().getUrl();}• We inject the ImageClient into our service's constructor.
• In our generate() method, we create an ImagePrompt with our description.
• We invoke call() to execute the request and extract the generated image URL.
3.2Refactoring with Dynamic Prompts and Structured Output
While our initial implementation works, it's limited to generating images with a fixed prompt. Also, we return a plain URL string that can be difficult to work with for clients.
To address these limitations, we'll refactor our service to use dynamic prompt construction and map the response to a structured Java object.
First, let's define a GeneratedImage record:
recordGeneratedImage(String url,String prompt,String style,String size
){}Next, let's refactor our service method:
GeneratedImagegenerate(String description,String style){String fullPrompt =String.format("%s in %s style", description, style);ImagePrompt prompt =newImagePrompt(fullPrompt,OpenAiImageOptions.builder().withQuality("hd").withN(1).withHeight(1024).withWidth(1024).build());ImageResponse response = imageClient.call(prompt);String imageUrl = response.getResult().getOutput().getUrl();returnnewGeneratedImage(imageUrl, fullPrompt, style,"1024x1024");}Key Changes:
- • Dynamic prompt construction with description and style parameters
- • Using
OpenAiImageOptionsto configure image quality and size - • Returning a structured
GeneratedImagerecord with metadata
3.3Exposing a REST API and Handling Errors
Now that we've implemented our service layer, let's expose a REST API on top of it:
@PostMapping("/images")ResponseEntity<GeneratedImage>generate(@RequestBodyImageGenerationRequest request){GeneratedImage response = imageService.generate(request.description, request.style);returnResponseEntity.ok(response);}recordImageGenerationRequest(String description,String style){}Additionally, as with communication with any external service, the configured image model can sometimes fail. Spring AI provides an OpenAiApiClientErrorException that provides an abstraction over all OpenAI errors.
Let's define an exception handler:
privatestaticfinalStringIMAGE_GENERATION_ERROR="Unable to generate image. Please try again later.";@ExceptionHandler(OpenAiApiClientErrorException.class)ProblemDetailhandle(OpenAiApiClientErrorException exception){
logger.error("OpenAI returned an error.", exception);returnProblemDetail.forStatusAndDetail(HttpStatus.SERVICE_UNAVAILABLE,IMAGE_GENERATION_ERROR);}Security Note:
We intentionally avoid exposing actual error details to prevent leaking sensitive information about our infrastructure or API keys. Instead, we log the full exception for debugging and return a user-friendly message.
Testing Our Application
Verify the implementation works correctly
Testing with HTTPie CLI
Let's use the API endpoint we've exposed to interact with and test our application:
http POST :8080/images description="A serene mountain landscape"style="watercolor painting"We send a POST request to our /images endpoint with our desired description and style.
Response:
{"url":"https://oaidalleapiprodscus.blob.core.windows.net/private/...","prompt":"A serene mountain landscape in watercolor painting style","style":"watercolor painting","size":"1024x1024"}Success!
We receive a generated image URL along with metadata about the request. This confirms that our application correctly constructs the prompt and receives the image generation response in a format that can be mapped to our GeneratedImage record.
Conclusion
In this article, we've explored integrating AI capabilities into a Spring Boot application using Spring AI.
We walked through the necessary configuration and implemented an image generation service using OpenAI's DALL-E model. We evolved our simple implementation from a fixed prompt to a more sophisticated solution using dynamic prompt construction and structured outputs.
ImageClient
Main entry point for image generation
ImagePrompt
Dynamic image generation with options
Structured Output
Map LLM responses to Java objects
While this introductory tutorial covers the fundamentals, Spring AI offers extensive AI capabilities that can be explored in our collection of Spring AI tutorials.